home *** CD-ROM | disk | FTP | other *** search
/ Freelog 22 / freelog 22.iso / BAS / Graphism / Chaos / data1.cab / Beispieldateien / Formulas / Compiler / dmj.ctr < prev   
Text File  |  2000-10-04  |  80KB  |  3,100 lines

  1. comment {
  2.   dmj-pub.uxf 2.1
  3.   Transformations for Ultra Fractal 2
  4.   by Damien M. Jones
  5.   April 2, 2000
  6.  
  7.   For more information about this formula collection,
  8.   please visit its home page:
  9.   
  10.       http://www.fractalus.com/ultrafractal/dmj-pub-uf.htm
  11.  
  12.   Most (all?) of the transformations in this file
  13.   have little or no redeeming mathematical value,
  14.   but are great for artistic control over fractal
  15.   images.
  16. }
  17.  
  18.  
  19. dmj-Blob-Clipping {
  20. //
  21. // This transform allows you to define clipping regions
  22. // using 2D "blobs". A single blob is circular, but blobs
  23. // "reach out" towards each other. You can add positive
  24. // blobs (which increase the clipping area) or negative
  25. // blobs (which "cut away" from the clipping area). Use
  26. // the eyedropper to choose your blobs, and then tweak
  27. // the strengths as appropriate. A strength of zero will
  28. // disable that particular blob. Up to eight blobs may
  29. // be used.
  30. //
  31. real sum;
  32. parameter real strength1;
  33. parameter complex center1;
  34. parameter real strength2;
  35. parameter complex center2;
  36. parameter real strength3;
  37. parameter complex center3;
  38. parameter real strength4;
  39. parameter complex center4;
  40. parameter real strength5;
  41. parameter complex center5;
  42. parameter real strength6;
  43. parameter complex center6;
  44. parameter real strength7;
  45. parameter complex center7;
  46. parameter real strength8;
  47. parameter complex center8;
  48. parameter int above;
  49. parameter real threshold;
  50.  
  51.     void transform(void)
  52.     {
  53.         sum = strength1 / |pixel-center1| + strength2 / |pixel-center2| + strength3 / |pixel-center3| + strength4 / |pixel-center4| + strength5 / |pixel-center5| + strength6 / |pixel-center6| + strength7 / |pixel-center7| + strength8 / |pixel-center8|;
  54.  
  55.         if  ((above == 0))
  56.         {
  57.             if  ((sum > threshold))
  58.             {
  59.                 solid = true;
  60.             }
  61.         }
  62.         else if  ((above == 1))
  63.         {
  64.             if  ((sum < threshold))
  65.             {
  66.                 solid = true;
  67.             }
  68.         }
  69. //  IF (sum > @threshold && @above == 0)
  70. //    #solid = true
  71. //  ELSEIF (sum < @threshold && @above == 1)
  72. //    #solid = true
  73. //  ENDIF
  74.   
  75.     }
  76.     void description(void)
  77.     {
  78.         this.title = "Blob Clipping";
  79.         this.helpfile = "dmj-pub\dmj-pub-uf-blobclip.htm";
  80.  
  81.    
  82.         threshold.caption = "Threshold";
  83.         threshold.default = 0.5;
  84.         threshold.hint = "Sets the threshold, above or below which points will be clipped. Smaller values will increase the size pf the clipping region.";
  85.   
  86.    
  87.         above.caption = "Clipping Region";
  88.         above.default = 0;
  89.         above.enum = "above threshold\nbelow threshold";
  90.         above.hint = "Set whether points above or below the threshold value will be clipped.";
  91.   
  92.   
  93.    
  94.         center1.caption = "Point 1 Center";
  95.         center1.default = (0,0);
  96.         center1.hint = "Sets the center point for this blob.";
  97.   
  98.    
  99.         strength1.caption = "Point 1 Strength";
  100.         strength1.default = 1.0;
  101.         strength1.hint = "Sets how 'strong' this blob is. Negative values will 'cut away' from the blobbed area.";
  102.   
  103.    
  104.         center2.caption = "Point 2 Center";
  105.         center2.default = (-1,0);
  106.         center2.hint = "Sets the center point for this blob.";
  107.   
  108.    
  109.         strength2.caption = "Point 2 Strength";
  110.         strength2.default = 0.5;
  111.         strength2.hint = "Sets how 'strong' this blob is. Negative values will 'cut away' from the blobbed area.";
  112.   
  113.    
  114.         center3.caption = "Point 3 Center";
  115.         center3.default = (0,0);
  116.         center3.hint = "Sets the center point for this blob.";
  117.   
  118.    
  119.         strength3.caption = "Point 3 Strength";
  120.         strength3.default = 0.0;
  121.         strength3.hint = "Sets how 'strong' this blob is. Negative values will 'cut away' from the blobbed area.";
  122.   
  123.    
  124.         center4.caption = "Point 4 Center";
  125.         center4.default = (0,0);
  126.         center4.hint = "Sets the center point for this blob.";
  127.   
  128.    
  129.         strength4.caption = "Point 4 Strength";
  130.         strength4.default = 0.0;
  131.         strength4.hint = "Sets how 'strong' this blob is. Negative values will 'cut away' from the blobbed area.";
  132.   
  133.    
  134.         center5.caption = "Point 5 Center";
  135.         center5.default = (0,0);
  136.         center5.hint = "Sets the center point for this blob.";
  137.   
  138.    
  139.         strength5.caption = "Point 5 Strength";
  140.         strength5.default = 0.0;
  141.         strength5.hint = "Sets how 'strong' this blob is. Negative values will 'cut away' from the blobbed area.";
  142.   
  143.    
  144.         center6.caption = "Point 6 Center";
  145.         center6.default = (0,0);
  146.         center6.hint = "Sets the center point for this blob.";
  147.   
  148.    
  149.         strength6.caption = "Point 6 Strength";
  150.         strength6.default = 0.0;
  151.         strength6.hint = "Sets how 'strong' this blob is. Negative values will 'cut away' from the blobbed area.";
  152.   
  153.    
  154.         center7.caption = "Point 7 Center";
  155.         center7.default = (0,0);
  156.         center7.hint = "Sets the center point for this blob.";
  157.   
  158.    
  159.         strength7.caption = "Point 7 Strength";
  160.         strength7.default = 0.0;
  161.         strength7.hint = "Sets how 'strong' this blob is. Negative values will 'cut away' from the blobbed area.";
  162.   
  163.    
  164.         center8.caption = "Point 8 Center";
  165.         center8.default = (0,0);
  166.         center8.hint = "Sets the center point for this blob.";
  167.   
  168.    
  169.         strength8.caption = "Point 8 Strength";
  170.         strength8.default = 0.0;
  171.         strength8.hint = "Sets how 'strong' this blob is. Negative values will 'cut away' from the blobbed area.";
  172.   
  173.     }
  174. }
  175.  
  176.  
  177. dmj-Clipping {
  178. //
  179. // Clipping Transformation
  180. // This fulfills much the same function as Luke
  181. // Plant's Scissors transform, but is geared
  182. // towards being easier to use (i.e. just point
  183. // and click).
  184. //
  185. complex p;
  186. complex r;
  187. real re;
  188. real te;
  189. parameter bool relative;
  190. parameter bool rotation;
  191. parameter complex sciright;
  192. parameter complex scicenter;
  193. parameter complex scitop;
  194. bool in;
  195. parameter int sciinside;
  196. parameter int scishape;
  197.  
  198.     void transform(void)
  199.     {
  200.         p = (0,0);
  201.         r = (0,0);
  202. //  complex s = (0,0)
  203.         re = 0.0;
  204.         te = 0.0;
  205.   
  206.   // determine pixel location
  207.         if  ((relative))
  208.         {// relative coordinates
  209.             p = real(screenpixel)/width + flip(imag(screenpixel)/height);
  210.         }
  211.         else
  212.         {
  213.                     // absolute coordinates
  214.             p = pixel;
  215.         }
  216.  
  217.   // determine right edge
  218.         if  ((rotation))
  219.         {// rotation is enabled
  220.             re = cabs(sciright-scicenter);
  221.             r = conj(sciright-scicenter) / re;
  222.         }
  223.         else if  ((relative))
  224.         {// relative coordinates
  225.             re = abs(real(sciright)-real(scicenter));
  226.             r = (1,0);
  227.         }
  228.         else
  229.         {
  230.                     // rotation is disabled
  231.             r = conj(exp(flip(angle)));
  232.             re = abs(real((sciright-scicenter)*r));
  233.         }
  234.  
  235.   // determine top edge
  236. //  IF (@skewing)                ; skewing is enabled
  237. //    float te = cabs(@scitop-@scicenter)
  238. //    complex s = conj(@scitop-@scicenter) / re
  239. //  ELSE                    ; rotation is disabled
  240.         te = abs(imag((scitop-scicenter)*r));
  241. //    complex s = (0,1)
  242. //  ENDIF
  243.   
  244.   // see if point is inside clipping shape
  245.         p = (p-scicenter) * r;
  246.  
  247.         in = (sciinside == 1);
  248.         if  ((scishape == 0))
  249.         {// circle
  250.             if  ((|p| < sqr(re)))
  251.             {
  252.                 in = !in;
  253.             }
  254.         }
  255.         else if  ((scishape == 1))
  256.         {// ellipse
  257.             if  ((sqr(real(p))/sqr(re)+sqr(imag(p))/sqr(te) < 1.0))
  258.             {
  259.                 in = !in;
  260.             }
  261.         }
  262.         else if  ((scishape == 2))
  263.         {// square
  264.             if  ((abs(real(p)) < re && abs(imag(p)) < re))
  265.             {
  266.                 in = !in;
  267.             }
  268.         }
  269.         else if  ((scishape == 3))
  270.         {// rectangular
  271.             if  ((abs(real(p)) < re && abs(imag(p)) < te))
  272.             {
  273.                 in = !in;
  274.             }
  275.         }
  276.         solid = in;
  277.  
  278.     }
  279.     void description(void)
  280.     {
  281.         this.title = "Clipping";
  282.         this.helpfile = "dmj-pub\dmj-pub-uf-clipping.htm";
  283.  
  284.    
  285.         scicenter.caption = "Clipping Center";
  286.         scicenter.default = (0,0);
  287.         scicenter.hint = "Sets the center of clipping.";
  288.   
  289.    
  290.         sciright.caption = "Clipping Right Edge";
  291.         sciright.default = (0,0);
  292.         sciright.hint = "Sets the right edge of the clipping shape. If rotation is enabled, sets the center of the right edge.";
  293.   
  294.    
  295.         scitop.caption = "Clipping Top Edge";
  296.         scitop.default = (0,0);
  297.         scitop.hint = "Sets the top edge of the clipping shape. Has no effect for Circle and Square clipping shapes." ;// If ;            skewing is enabled, sets the center of the ;        top edge."
  298.   
  299.    
  300.         scishape.caption = "Clipping Shape";
  301.         scishape.default = 2;
  302.         scishape.enum = "circle\nellipse\nsquare\nrectangle";
  303.         scishape.hint = "Selects the clipping shape.";
  304.   
  305.    
  306.         rotation.caption = "Allow Rotation";
  307.         rotation.default = FALSE;
  308.         rotation.hint = "If enabled, you can use the Right Edge setting to also select a rotation for the clipping shape.";
  309.   
  310. //  param skewing
  311. //    caption = "Allow Skewing"
  312. //    default = FALSE
  313. //    hint = "If enabled, you can use the Top Edge setting ;            to also select a skewing for the clipping shape."
  314. //  endparam
  315.    
  316.         sciinside.caption = "Clipping Region";
  317.         sciinside.default = 1;
  318.         sciinside.enum = "inside\noutside";
  319.   
  320.    
  321.         relative.caption = "Screen-Relative";
  322.         relative.default = FALSE;
  323.         relative.hint = "If set, all clipping coordinates are relative to the fractal window. This will leave the clipping shape intact while zooming, but make it harder to enter coordinates for clipping.";
  324.   
  325.     }
  326. }
  327.  
  328.  
  329. dmj-EggScissors {
  330. //
  331. // Special Egg Scissors Transform
  332. // This performs much the same function as the
  333. // general clipping transform, but uses an egg
  334. // shape.
  335. //
  336. complex c;
  337. parameter complex eggcenter;
  338. parameter bool centermove;
  339. complex r;
  340. parameter real Parm_angle;
  341. parameter real aspect;
  342. real d;
  343. parameter real diameter;
  344. parameter real eggorder;
  345. parameter bool egginside;
  346. parameter real threshold;
  347.  
  348.     void transform(void)
  349.     {
  350.         c = eggcenter;// assume egg center is fixed
  351.         if  ((centermove))
  352.         {// relative egg center requested
  353.             c = center;// egg center is image center
  354.         }
  355.         r = (0,1) ^ (Parm_angle / 90.0);// rotation vector
  356.         z = (pixel-c) * r;// apply translation and rotation
  357.         z = real(z) + flip(imag(z) * aspect);// apply aspect
  358.         d = (cabs(z-flip(diameter)*2) + cabs(z)*eggorder*0.5) / (eggorder+1);
  359.         if  ((egginside))
  360.         {// want solid inside
  361.             if  ((d < threshold))
  362.             {// point is inside egg
  363.                 solid = true;// color it solid
  364.             }
  365.         }
  366.         else
  367.         {
  368.                     // want solid outside
  369.             if  ((d > threshold))
  370.             {// point is outside egg
  371.                 solid = true;
  372.             }
  373.         }
  374.  
  375.     }
  376.     void description(void)
  377.     {
  378.         this.title = "Egg Scissors";
  379.         this.helpfile = "dmj-pub\dmj-pub-uf-egg.htm";
  380.   
  381.    
  382.         eggorder.caption = "Egginess";
  383.         eggorder.default = 3.0;
  384.         eggorder.hint = "Adjusts how non-circular the curve is.";
  385.   
  386.    
  387.         eggcenter.caption = "Egg Center";
  388.         eggcenter.default = (0,0);
  389.         eggcenter.hint = "Sets the location of one focus of the egg shape.";
  390.   
  391.    
  392.         centermove.caption = "Use Screen Center";
  393.         centermove.default = TRUE;
  394.         centermove.hint = "If set, the egg focus will be at the center of the window, regardless of the Egg Center setting.";
  395.   
  396.    
  397.         egginside.caption = "Solid Inside";
  398.         egginside.default = FALSE;
  399.         egginside.hint = "If set, the inside of the egg will be solid. Otherwise, the outside of the egg will be solid.";
  400.   
  401.    
  402.         aspect.caption = "Aspect Ratio";
  403.         aspect.default = 1.0;
  404.         aspect.min = 0.0000000001;
  405.         aspect.hint = "This is how square the egg curve is.  You can distort the curve by using a value other than 1.0.";
  406.   
  407.    
  408.         threshold.caption = "Threshold";
  409.         threshold.default = 0.5;
  410.         threshold.min = 0;
  411.         threshold.hint = "This is the distance to the edge of the egg curve.";
  412.   
  413.    
  414.         diameter.caption = "Diameter";
  415.         diameter.default = 0.5;
  416.         diameter.hint = "This is the distance between focal points of the egg curve.";
  417.   
  418.    
  419.         Parm_angle.caption = "Rotation";
  420.         Parm_angle.default = 0.0;
  421.         Parm_angle.hint = "This is the angle, in degrees, that the egg curve should be rotated.";
  422.   
  423.     }
  424. }
  425.  
  426.  
  427. dmj-fBm-Clipping {
  428. //
  429. // fBm-based clipping.
  430. // This performs clipping based on fBm textures.
  431. //
  432. complex r;
  433. parameter real Parm_angle;
  434. complex r2;
  435. parameter real anglestep;
  436. complex p;
  437. parameter real scale;
  438. parameter complex offset;
  439. real sum;
  440. real freq;
  441. int i;
  442. parameter real octaves;
  443. real bx0;
  444. real by0;
  445. real bx1;
  446. real by1;
  447. real rx0;
  448. real ry0;
  449. real rx1;
  450. real ry1;
  451. real b00;
  452. parameter real power;
  453. real b10;
  454. real b01;
  455. real b11;
  456. real g_b00_0;
  457. real g_b10_0;
  458. real g_b01_0;
  459. real g_b11_0;
  460. real g_b00_1;
  461. real g_b10_1;
  462. real g_b01_1;
  463. real g_b11_1;
  464. real d;
  465. real u1;
  466. real v1;
  467. real u2;
  468. real v2;
  469. real sx;
  470. real sy;
  471. real a;
  472. real b;
  473. parameter real step;
  474. parameter int above;
  475. parameter real threshold;
  476.  
  477.     void transform(void)
  478.     {
  479.         r = (0,1) ^ (Parm_angle / 90.0);
  480.         r2 = (0,1) ^ (anglestep / 90.0);
  481. //  complex r3 = (0,1) ^ (@distangle / 90.0)
  482.         p = pixel * scale * r + offset;
  483.  
  484.         sum = 0.0;
  485.         freq = 1.0;
  486.         i = octaves;
  487.         while  ((i > 0))
  488.         {
  489.     // determine integer coordinate for corners of square
  490.     // surrounding p
  491.             bx0 = floor(real(p)) % 256;
  492.             by0 = floor(imag(p)) % 256;
  493.             if  ((bx0 < 0))
  494.             {
  495.                 bx0 = bx0 + 256;
  496.             }
  497.             if  ((by0 < 0))
  498.             {
  499.                 by0 = by0 + 256;
  500.             }
  501.             bx1 = (bx0 + 1) % 256;
  502.             by1 = (by0 + 1) % 256;
  503.  
  504.             rx0 = real(p) - floor(real(p));
  505.             ry0 = imag(p) - floor(imag(p));
  506.             rx1 = rx0 - 1;
  507.             ry1 = ry0 - 1;
  508.     
  509.     // create a "random" index for each corner
  510.     // (this is where Intel's version differs from Perlin's;
  511.     // I used Intel's version because it doesn't require a
  512.     // pre-computed random table, which is difficult to manage
  513.     // in UF.)
  514.             b00 = (bx0^power % 65536 + by0)^power % 65536;
  515.             b10 = (bx1^power % 65536 + by0)^power % 65536;
  516.             b01 = (bx0^power % 65536 + by1)^power % 65536;
  517.             b11 = (bx1^power % 65536 + by1)^power % 65536;
  518.  
  519.     // produce a "random" vector for each corner
  520.             g_b00_0 = (b00)^power*0.25 % 512 - 256;
  521.             g_b10_0 = (b10)^power*0.25 % 512 - 256;
  522.             g_b01_0 = (b01)^power*0.25 % 512 - 256;
  523.             g_b11_0 = (b11)^power*0.25 % 512 - 256;
  524.             g_b00_1 = (b00+1)^power*0.25 % 512 - 256;
  525.             g_b10_1 = (b10+1)^power*0.25 % 512 - 256;
  526.             g_b01_1 = (b01+1)^power*0.25 % 512 - 256;
  527.             g_b11_1 = (b11+1)^power*0.25 % 512 - 256;
  528.     
  529.     // normalize each vector
  530.             d = 0.0;//
  531.             d = 1 / sqrt(sqr(g_b00_0) + sqr(g_b00_1));
  532.             g_b00_0 = g_b00_0 * d;
  533.             g_b00_1 = g_b00_1 * d;
  534.             d = 1 / sqrt(sqr(g_b10_0) + sqr(g_b10_1));
  535.             g_b10_0 = g_b10_0 * d;
  536.             g_b10_1 = g_b10_1 * d;
  537.             d = 1 / sqrt(sqr(g_b01_0) + sqr(g_b01_1));
  538.             g_b01_0 = g_b01_0 * d;
  539.             g_b01_1 = g_b01_1 * d;
  540.             d = 1 / sqrt(sqr(g_b11_0) + sqr(g_b11_1));
  541.             g_b11_0 = g_b11_0 * d;
  542.             g_b11_1 = g_b11_1 * d;
  543.     
  544.     // produce colors for each corner
  545.             u1 = rx0 * g_b00_0 + ry0 * g_b00_1;
  546.             v1 = rx1 * g_b10_0 + ry0 * g_b10_1;
  547.             u2 = rx0 * g_b01_0 + ry1 * g_b01_1;
  548.             v2 = rx1 * g_b11_0 + ry1 * g_b11_1;
  549.     
  550.     // interpolate between corners using
  551.     // bilinear filtering
  552.             sx = sqr(rx0) * (3 - rx0*2);
  553.             sy = sqr(ry0) * (3 - ry0*2);
  554.             a = u1 + sx*(v1-u1);
  555.             b = u2 + sx*(v2-u2);
  556.     
  557.             sum = sum + (a + sy*(b-a))*freq;
  558.             freq = freq * step;
  559.             p = p * r2 / step;
  560.             i = i - 1;
  561.         }
  562.  
  563.         if  ((above == 0))
  564.         {
  565.             if  ((sum > threshold))
  566.             {
  567.                 solid = true;
  568.             }
  569.         }
  570.         else if  ((above == 1))
  571.         {
  572.             if  ((sum < threshold))
  573.             {
  574.                 solid = true;
  575.             }
  576.         }
  577. //  IF (sum > @threshold && @above == 0)
  578. //    #solid = true
  579. //  ELSEIF (sum < @threshold && @above == 1)
  580. //    #solid = true
  581. //  ENDIF
  582.   
  583.     }
  584.     void description(void)
  585.     {
  586.         this.title = "fBm Clipping";
  587.         this.helpfile = "dmj-pub\dmj-pub-uf-fbmclip.htm";
  588.  
  589.    
  590.         threshold.caption = "Threshold";
  591.         threshold.default = 0.0;
  592.         threshold.hint = "Sets the threshold, above or below which points will be clipped.";
  593.   
  594.    
  595.         above.caption = "Clipping Region";
  596.         above.default = 0;
  597.         above.enum = "above threshold\nbelow threshold";
  598.         above.hint = "Set whether points above or below the threshold value will be clipped.";
  599.   
  600.    
  601.         offset.caption = "Noise Offset";
  602.         offset.default = (0,0);
  603.         offset.hint = "This is the offset of the pattern. You can use this to shift the pattern around on the complex plane.";
  604.   
  605.    
  606.         scale.caption = "Noise Scale";
  607.         scale.default = 1.0;
  608.         scale.hint = "This is the overall scale of the noise.";
  609.   
  610.    
  611.         Parm_angle.caption = "Noise Rotation";
  612.         Parm_angle.default = 0.0;
  613.         Parm_angle.hint = "This is the angle, in degrees, of the noise.";
  614.   
  615.    
  616.         step.caption = "Noise Scale Step";
  617.         step.default = 0.5;
  618.         step.hint = "This is the step in scale between noise iterations.";
  619.   
  620.    
  621.         anglestep.caption = "Noise Rotation Step";
  622.         anglestep.default = 37.0;
  623.         anglestep.hint = "This is the angle, in degrees, to rotate between noise iterations.";
  624.   
  625.    
  626.         octaves.caption = "Noise Octaves";
  627.         octaves.default = 7;
  628.         octaves.min = 1;
  629.         octaves.hint = "This is the number of iterations of the noise formula.";
  630.   
  631.    
  632.         power.caption = "Noise Exponent";
  633.         power.default = 2.0;
  634.         power.hint = "This is the exponent used to scramble numbers.";
  635.   
  636.     }
  637. }
  638.  
  639.  
  640. dmj-fBm-Glass1 {
  641. //
  642. // fBm-based glass distortion.
  643. // This provides one-dimensional distortion based
  644. // on fBm textures.
  645. //
  646. complex c;
  647. parameter complex distcenter;
  648. parameter bool centermove;
  649. complex r;
  650. parameter real Parm_angle;
  651. complex r2;
  652. parameter real anglestep;
  653. complex r3;
  654. parameter real distangle;
  655. complex p;
  656. parameter real scale;
  657. parameter complex offset;
  658. real sum;
  659. real freq;
  660. complex v;
  661. int i;
  662. parameter real octaves;
  663. real bx0;
  664. real by0;
  665. real bx1;
  666. real by1;
  667. real rx0;
  668. real ry0;
  669. real rx1;
  670. real ry1;
  671. real b00;
  672. parameter real power;
  673. real b10;
  674. real b01;
  675. real b11;
  676. real g_b00_0;
  677. real g_b10_0;
  678. real g_b01_0;
  679. real g_b11_0;
  680. real g_b00_1;
  681. real g_b10_1;
  682. real g_b01_1;
  683. real g_b11_1;
  684. real d;
  685. real u1;
  686. real v1;
  687. real u2;
  688. real v2;
  689. real sx;
  690. real sy;
  691. real a;
  692. real b;
  693. parameter real step;
  694. parameter int style;
  695. parameter real distortion;
  696.  
  697.     void transform(void)
  698.     {
  699.         c = distcenter;
  700.         if  ((centermove))
  701.         {
  702.             c = center;
  703.         }
  704.  
  705.         r = (0,1) ^ (Parm_angle / 90.0);
  706.         r2 = (0,1) ^ (anglestep / 90.0);
  707.         r3 = (0,1) ^ (distangle / 90.0);
  708.         p = pixel * scale * r + offset;
  709.  
  710.         sum = 0.0;
  711.         freq = 1.0;
  712.         v = (0,0);
  713.         i = octaves;
  714.         while  ((i > 0))
  715.         {
  716.     // determine integer coordinate for corners of square
  717.     // surrounding p
  718.             bx0 = floor(real(p)) % 256;
  719.             by0 = floor(imag(p)) % 256;
  720.             if  ((bx0 < 0))
  721.             {
  722.                 bx0 = bx0 + 256;
  723.             }
  724.             if  ((by0 < 0))
  725.             {
  726.                 by0 = by0 + 256;
  727.             }
  728.             bx1 = (bx0 + 1) % 256;
  729.             by1 = (by0 + 1) % 256;
  730.  
  731.             rx0 = real(p) - floor(real(p));
  732.             ry0 = imag(p) - floor(imag(p));
  733.             rx1 = rx0 - 1;
  734.             ry1 = ry0 - 1;
  735.     
  736.     // create a "random" index for each corner
  737.     // (this is where Intel's version differs from Perlin's;
  738.     // I used Intel's version because it doesn't require a
  739.     // pre-computed random table, which is difficult to manage
  740.     // in UF.)
  741.             b00 = (bx0^power % 65536 + by0)^power % 65536;
  742.             b10 = (bx1^power % 65536 + by0)^power % 65536;
  743.             b01 = (bx0^power % 65536 + by1)^power % 65536;
  744.             b11 = (bx1^power % 65536 + by1)^power % 65536;
  745.  
  746.     // produce a "random" vector for each corner
  747.             g_b00_0 = (b00)^power*0.25 % 512 - 256;
  748.             g_b10_0 = (b10)^power*0.25 % 512 - 256;
  749.             g_b01_0 = (b01)^power*0.25 % 512 - 256;
  750.             g_b11_0 = (b11)^power*0.25 % 512 - 256;
  751.             g_b00_1 = (b00+1)^power*0.25 % 512 - 256;
  752.             g_b10_1 = (b10+1)^power*0.25 % 512 - 256;
  753.             g_b01_1 = (b01+1)^power*0.25 % 512 - 256;
  754.             g_b11_1 = (b11+1)^power*0.25 % 512 - 256;
  755.     
  756.     // normalize each vector
  757.             d = 0.0;//
  758.             d = 1 / sqrt(sqr(g_b00_0) + sqr(g_b00_1));
  759.             g_b00_0 = g_b00_0 * d;
  760.             g_b00_1 = g_b00_1 * d;
  761.             d = 1 / sqrt(sqr(g_b10_0) + sqr(g_b10_1));
  762.             g_b10_0 = g_b10_0 * d;
  763.             g_b10_1 = g_b10_1 * d;
  764.             d = 1 / sqrt(sqr(g_b01_0) + sqr(g_b01_1));
  765.             g_b01_0 = g_b01_0 * d;
  766.             g_b01_1 = g_b01_1 * d;
  767.             d = 1 / sqrt(sqr(g_b11_0) + sqr(g_b11_1));
  768.             g_b11_0 = g_b11_0 * d;
  769.             g_b11_1 = g_b11_1 * d;
  770.     
  771.     // produce colors for each corner
  772.             u1 = rx0 * g_b00_0 + ry0 * g_b00_1;
  773.             v1 = rx1 * g_b10_0 + ry0 * g_b10_1;
  774.             u2 = rx0 * g_b01_0 + ry1 * g_b01_1;
  775.             v2 = rx1 * g_b11_0 + ry1 * g_b11_1;
  776.     
  777.     // interpolate between corners using
  778.     // bilinear filtering
  779.             sx = sqr(rx0) * (3 - rx0*2);
  780.             sy = sqr(ry0) * (3 - ry0*2);
  781.             a = u1 + sx*(v1-u1);
  782.             b = u2 + sx*(v2-u2);
  783.     
  784.             sum = sum + (a + sy*(b-a))*freq;
  785.             freq = freq * step;
  786.             p = p * r2 / step;
  787.             i = i - 1;
  788.         }
  789.  
  790.         if  ((style == 0))
  791.         {// radial distortion
  792.             v = (pixel-c)/cabs(pixel-c) * r3;// use vector based on angle to distortion center
  793.         }
  794.         else if  ((style == 1))
  795.         {// linear distortion
  796.             v = r3;// just use rotation vector
  797.         }
  798.         pixel = pixel + v * sum*0.5*distortion;
  799.   
  800.     }
  801.     void description(void)
  802.     {
  803.         this.title = "fBm Glass 1";
  804.         this.helpfile = "dmj-pub\dmj-pub-uf-fbmg1.htm";
  805.  
  806.    
  807.         distortion.caption = "Distortion Strength";
  808.         distortion.default = 1.0;
  809.         distortion.hint = "This is the amount the noise distorts the image.";
  810.   
  811.    
  812.         style.caption = "Distortion Style";
  813.         style.default = 0;
  814.         style.enum = "radial\nlinear";
  815.         style.hint = "This selects whether the distortion will be focused around a single point, or directed along a line.";
  816.   
  817.    
  818.         distangle.caption = "Distortion Angle";
  819.         distangle.default = 0.0;
  820.         distangle.hint = "This is the angle to rotate the distortion.";
  821.   
  822.    
  823.         distcenter.caption = "Distortion Center";
  824.         distcenter.default = (0,0);
  825.         distcenter.hint = "Sets the center of distortion.  If Use Screen Center is set, this item is ignored.";
  826.   
  827.    
  828.         centermove.caption = "Use Screen Center";
  829.         centermove.default = TRUE;
  830.         centermove.hint = "If set, distortion will be around the center of the window, regardless of the Distortion Center setting.";
  831.   
  832.    
  833.         offset.caption = "Noise Offset";
  834.         offset.default = (0,0);
  835.         offset.hint = "This is the offset of the pattern. You can use this to shift the pattern around on the complex plane.";
  836.   
  837.    
  838.         scale.caption = "Noise Scale";
  839.         scale.default = 1.0;
  840.         scale.hint = "This is the overall scale of the noise.";
  841.   
  842.    
  843.         Parm_angle.caption = "Noise Rotation";
  844.         Parm_angle.default = 0.0;
  845.         Parm_angle.hint = "This is the angle, in degrees, of the noise.";
  846.   
  847.    
  848.         step.caption = "Noise Scale Step";
  849.         step.default = 0.5;
  850.         step.hint = "This is the step in scale between noise iterations.";
  851.   
  852.    
  853.         anglestep.caption = "Noise Rotation Step";
  854.         anglestep.default = 37.0;
  855.         anglestep.hint = "This is the angle, in degrees, to rotate between noise iterations.";
  856.   
  857.    
  858.         octaves.caption = "Noise Octaves";
  859.         octaves.default = 7;
  860.         octaves.min = 1;
  861.         octaves.hint = "This is the number of iterations of the noise formula.";
  862.   
  863.    
  864.         power.caption = "Noise Exponent";
  865.         power.default = 2.0;
  866.         power.hint = "This is the exponent used to scramble numbers.";
  867.   
  868.     }
  869. }
  870.  
  871.  
  872. dmj-Forces {
  873. //
  874. // This uses the Mosaic algorithm to sprinkle the image
  875. // with "force points" which attract or repel pixels in
  876. // the image. For any given pixel, its final location is
  877. // the sum of all the forces acting on it. You cannot place
  878. // force points manually; they are placed by the same
  879. // algorithm which places mosaic tile centers.
  880. //
  881. complex center2;
  882. parameter complex moscenter;
  883. parameter bool centermove;
  884. int i;
  885. real d;
  886. real random1;
  887. parameter real seed1;
  888. real random2;
  889. parameter real seed2;
  890. real random3;
  891. parameter real seed3;
  892. complex p;
  893. complex point1;
  894. real r1;
  895. real range;
  896. parameter real mostiles;
  897. parameter real mosscale;
  898. parameter real mosmax;
  899. parameter real mosmin;
  900.  
  901.     void transform(void)
  902.     {
  903.         center2 = moscenter;
  904.         if  ((centermove))
  905.         {
  906.             center2 = center;
  907.         }
  908.   
  909.         i = 0;
  910.         d = 0;
  911.         random1 = seed1;
  912.         random2 = seed2;
  913.         random3 = seed3;
  914.         p = 0;
  915.         point1 = 0;
  916.         r1 = 0;
  917.         range = 1.0 / 2147483648.0;
  918.  
  919.         while  ((i < mostiles))
  920.         {// still another tile to check
  921.             random1 = (random1 * 1103515245 + 12345) % 2147483648.0;
  922.             random2 = (random2 * 1103515245 + 12345) % 2147483648.0;
  923.             random3 = (random3 * 1103515245 + 12345) % 2147483648.0;
  924.             p = center2 + ((random1 - 1073741824) + flip(random2 - 1073741824)) * range * mosscale;
  925.             d = |p - pixel|;
  926.             r1 = (random3 * range) * (mosmax-mosmin) + mosmin;
  927.  
  928.             point1 = point1 + r1/d*(p-pixel);
  929.             i = i + 1;
  930.         }
  931.  
  932.         pixel = pixel + point1;
  933.   
  934.     }
  935.     void description(void)
  936.     {
  937.         this.title = "Forces";
  938.         this.helpfile = "dmj-pub\dmj-pub-uf-forces.htm";
  939.   
  940.    
  941.         mostiles.caption = "Number of Points";
  942.         mostiles.default = 500;
  943.         mostiles.hint = "Sets the number of force points. More points take longer to render.";
  944.   
  945.    
  946.         moscenter.caption = "Force Area Center";
  947.         moscenter.default = (0,0);
  948.         moscenter.hint = "Sets the center of the force area. The cluster of force points will be centered at this point.";
  949.   
  950.    
  951.         centermove.caption = "Use Screen Center";
  952.         centermove.default = TRUE;
  953.         centermove.hint = "If set, the force area center is assumed to be at the center of the window, regardless of the Force Area Center setting.";
  954.   
  955.    
  956.         mosscale.caption = "Point Density";
  957.         mosscale.default = 5.0;
  958.         mosscale.hint = "Specifies the overall scale of the points. Smaller numbers will pack the points together more closely.";
  959.   
  960.    
  961.         mosmin.caption = "Minimum Force";
  962.         mosmin.default = -0.1;
  963.         mosmin.hint = "This is the minimum force (strongest attraction) a point may have.";
  964.   
  965.    
  966.         mosmax.caption = "Maximum Force";
  967.         mosmax.default = 0.1;
  968.         mosmax.hint = "This is the maximum force (strongest repulsion) a point may have.";
  969.   
  970.    
  971.         seed1.caption = "Random Seed 1";
  972.         seed1.default = 51853571;
  973.         seed1.hint = "This is the 'seed' for the random number generator for horizontal positions.";
  974.   
  975.    
  976.         seed2.caption = "Random Seed 2";
  977.         seed2.default = 8072177;
  978.         seed2.hint = "This is the 'seed' for the random number generator for vertical positions.";
  979.   
  980.    
  981.         seed3.caption = "Random Seed 3";
  982.         seed3.default = 654187327;
  983.         seed3.hint = "This is the 'seed' for the random number generator for rotations.";
  984.   
  985.     }
  986. }
  987.  
  988.  
  989. dmj-Inversion {
  990. //
  991. // This is a generalization of inversion, based on the
  992. // ideas first presented by Kerry Mitchell in his
  993. // Inversion fractal formula. This is a general-purpose
  994. // transform and can be used with any fractal.
  995. //
  996. // Thanks to Kerry also for some optimizations on this
  997. // formula.
  998. //
  999. complex c;
  1000. parameter complex invcenter;
  1001. parameter bool centermove;
  1002. complex r;
  1003. parameter real Parm_angle;
  1004. parameter real aspect;
  1005. real d;
  1006. parameter int invtype;
  1007. parameter complex invpower;
  1008. parameter real invscale;
  1009. parameter real invorder;
  1010. parameter real diameter;
  1011.  
  1012.     void transform(void)
  1013.     {
  1014.         c = invcenter;// assume inversion center is fixed
  1015.         if  ((centermove))
  1016.         {// relative inversion center requested
  1017.             c = center;// inversion center is image center
  1018.         }
  1019.         r = (0,1) ^ (Parm_angle / 90.0);// rotation vector
  1020.         z = (pixel-c) * r;// apply translation and rotation
  1021.         z = real(z) + flip(imag(z) * aspect);// apply aspect
  1022.         d = 1.0;
  1023.         if  ((invtype == 4))
  1024.         {// one axis only inversion
  1025.             if  ((invpower == (-1,0)))
  1026.             {// standard power
  1027.                 z = real(z) + invscale*flip(1/imag(z));// invert just the one axis
  1028.             }
  1029.             else
  1030.             {
  1031.                     // general power
  1032.                 z = real(z) + invscale*flip(imag(z)^invpower);// do inversion
  1033.             }
  1034.     
  1035.         }
  1036.         else
  1037.         {
  1038.                     // any other inversion type
  1039.  
  1040. //    IF (@invtype == 0)            ; ellipse
  1041. //                    ; same distance everywhere
  1042.     
  1043.             if  ((invtype == 1))
  1044.             {// hypercross
  1045. //      d = imag(z) / real(z)        ; slope of line passing through z
  1046. //      d = 1.0 / sqrt(abs(d + 1.0/d))    ; distance from origin to hypercross
  1047. //                        ;   through z
  1048.                 d = sqrt(abs(real(z)*imag(z))/|z|);// Kerry's simplification
  1049.  
  1050.             }
  1051.             else if  ((invtype == 2))
  1052.             {// flower
  1053.                 d = atan2(z);// angle to z
  1054.                 d = abs(cos(d*invorder)+diameter);// distance from origin to flower at
  1055.                           //   angle z
  1056.  
  1057.             }
  1058.             else if  ((invtype == 3))
  1059.             {// lines
  1060.                 d = sqrt(sqr(real(z)/imag(z))+1);// distance from origin to horizontal
  1061.                         //   line through z
  1062.  
  1063.             }
  1064. //  z = z*d / sqr(cabs(z))        ; do inversion (stupid way)
  1065.             if  ((invpower == (-1,0)))
  1066.             {// standard power
  1067.                 z = invscale*z*d / |z|;// do inversion (Kerry-optimized)
  1068.             }
  1069.             else
  1070.             {
  1071.                     // general power
  1072.                 z = invscale*z*d * cabs(z)^(invpower-1);// do inversion
  1073.             }
  1074.  
  1075.         }
  1076.  
  1077.         z = real(z) + flip(imag(z) / aspect);// undo aspect
  1078.         pixel = z * conj(r) + c;// undo rotation and translation
  1079.  
  1080.     }
  1081.     void description(void)
  1082.     {
  1083.         this.title = "General Inversion";
  1084.         this.helpfile = "dmj-pub\dmj-pub-uf-inversion.htm";
  1085.   
  1086.    
  1087.         invtype.caption = "Inversion Curve";
  1088.         invtype.default = 0;
  1089.         invtype.enum = "ellipse\nhypercross\nflower\nlines\none axis";
  1090.         invtype.hint = "Sets the shape of the curve through which inversion is done.";
  1091.   
  1092.    
  1093.         invscale.caption = "Inversion Scale";
  1094.         invscale.default = 1.0;
  1095.         invscale.hint = "Scale of the inversion. This performs a similar function to changing the magnitude of the fractal zoom.";
  1096.   
  1097.    
  1098.         invorder.caption = "Inversion Order";
  1099.         invorder.default = 3.0;
  1100.         invorder.hint = "Number of leaves for the flower curve.";
  1101.   
  1102.    
  1103.         invcenter.caption = "Inversion Center";
  1104.         invcenter.default = (0,0);
  1105.         invcenter.hint = "Sets the center of the inversion.";
  1106.   
  1107.    
  1108.         centermove.caption = "Use Screen Center";
  1109.         centermove.default = TRUE;
  1110.         centermove.hint = "If set, inversion will be around the center of the window, regardless of the Inversion Center setting.";
  1111.   
  1112.    
  1113.         aspect.caption = "Aspect Ratio";
  1114.         aspect.default = 1.0;
  1115.         aspect.min = 0.0000000001;
  1116.         aspect.hint = "This is how square the inversion curve is.  You can distort the curve by using a value other than 1.0.";
  1117.   
  1118.    
  1119.         diameter.caption = "Diameter";
  1120.         diameter.default = 1.5;
  1121.         diameter.hint = "This is the diameter of the inversion curve. Note this only matters for the 'flower' curve type.";
  1122.   
  1123.    
  1124.         Parm_angle.caption = "Rotation";
  1125.         Parm_angle.default = 0.0;
  1126.         Parm_angle.hint = "This is the angle, in degrees, that the inversion curve should be rotated.";
  1127.   
  1128.    
  1129.         invpower.caption = "Exponent";
  1130.         invpower.default = (-1,0);
  1131.         invpower.hint = "Gives the inversion exponent. (-1,0) gives the classic 1/z inversion type.";
  1132.   
  1133.     }
  1134. }
  1135.  
  1136.  
  1137. dmj-Julia {
  1138. //
  1139. // This does a few Julia-set iterations to warp
  1140. // the fractal shape. Try using it with a
  1141. // Newton fractal.
  1142. //
  1143. int i;
  1144. parameter real iters;
  1145. parameter complex offset;
  1146. parameter real bailout;
  1147. parameter complex power;
  1148. parameter complex seed;
  1149.  
  1150.     void transform(void)
  1151.     {
  1152.         i = iters;
  1153.         z = pixel-offset;
  1154.         while  ((i > 0 && |z| <= bailout))
  1155.         {
  1156.             z = z^power + seed;
  1157.             i = i - 1;
  1158.         }
  1159.         if  ((|z| > bailout))
  1160.         {
  1161.             solid = true;
  1162.         }
  1163.         else
  1164.         {
  1165.  
  1166.             pixel = z+offset;
  1167.         }
  1168.  
  1169.     }
  1170.     void description(void)
  1171.     {
  1172.         this.title = "Julia";
  1173.         this.helpfile = "dmj-pub\dmj-pub-uf-mjpnx.htm";
  1174.  
  1175.    
  1176.         iters.caption = "Iterations";
  1177.         iters.default = 4;
  1178.         iters.hint = "Number of iterations to do before calculating the fractal. Use a small number.";
  1179.   
  1180.    
  1181.         offset.caption = "Offset";
  1182.         offset.default = (0,0);
  1183.         offset.hint = "Offsets the Julia distortion.";
  1184.   
  1185.    
  1186.         seed.caption = "Julia Seed";
  1187.         seed.default = (0,0);
  1188.         seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
  1189.   
  1190.    
  1191.         power.caption = "Exponent";
  1192.         power.default = (2,0);
  1193.         power.hint = "Overall exponent for the equation.  (2,0) gives the classic Julia type.";
  1194.   
  1195.    
  1196.         bailout.caption = "Bailout";
  1197.         bailout.default = 1.0e20;
  1198.         bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Julia set anymore. Bailed-out points will be solid-colored.";
  1199.   
  1200.     }
  1201. }
  1202.  
  1203.  
  1204. dmj-Kaleidoscope {
  1205. //
  1206. // Kaleidoscope Transformation
  1207. // This can be used to simulate many different
  1208. // kinds of symmetry.
  1209. //
  1210. // Changes:
  1211. // - When using "slice" mode, points not part of
  1212. //   the slice will be colored using the solid
  1213. //   color.  You can use this to assemble several
  1214. //   slices into the same image.
  1215. //
  1216. real r2;
  1217. real d;
  1218. complex r;
  1219. parameter real Parm_angle;
  1220. complex c;
  1221. parameter complex symcenter;
  1222. parameter bool centermove;
  1223. complex z2;
  1224. parameter real symorder;
  1225. parameter int symreflect;
  1226.  
  1227.     void transform(void)
  1228.     {
  1229.         r2 = 0.0;
  1230.         d = 0.0;
  1231.         r = (0,1) ^ (Parm_angle/90);// complex rotation vector
  1232.         c = symcenter;// assume symmetry center is fixed
  1233.         if  ((centermove))
  1234.         {// relative symmetry center requested
  1235.             c = center;// symmetry center is image center
  1236.         }
  1237.         z2 = pixel - c;// get coordinate relative to symcenter
  1238.  
  1239.   // convert z2 into angle and distance  
  1240.         r2 = real(atan(imag(z2)/real(z2)));// basic arctangent, -pi/2 < atan < pi/2
  1241.         if  ((real(z2) < 0))
  1242.         {// pointing to left
  1243.             r2 = r2 + pi;// rotate 180 degrees
  1244.         }
  1245.         if  ((r2 < 0))
  1246.         {// negative angle (we want 0 < atan < pi*2)
  1247.             r2 = r2 + pi * 2;// rotate 360 degrees
  1248.         }
  1249.         d = cabs(z2);// distance from symcenter
  1250.  
  1251.         if  ((symorder > 0))
  1252.         {// Zero symmetry disables the transform.
  1253.     // apply symmetry
  1254.             if  ((symreflect == 0))
  1255.             {// reflective
  1256.                 r2 = r2 - floor(r2*symorder/pi/2)*pi*2/symorder;
  1257.                 if  ((r2 > pi/symorder))
  1258.                 {// upper half of the range
  1259.                     r2 = pi*2/symorder - r2;// reflect angle
  1260.                 }
  1261.             }
  1262.             else if  ((symreflect == 1))
  1263.             {// left symmetry
  1264.                 r2 = r2 - floor(r2*symorder/pi/2)*pi*2/symorder;
  1265.             }
  1266.             else if  ((symreflect == 2))
  1267.             {// right symmetry
  1268.                 r2 = r2 - floor(r2*symorder/pi/2)*pi*2/symorder;
  1269.                 r2 = pi*2/symorder - r2;// always reflect this
  1270.             }
  1271.             else if  ((symreflect == 3))
  1272.             {// slice-only symmetry
  1273.                 if  ((r2 > pi*2/symorder))
  1274.                 {// outside of slice
  1275.                     r2 = 0;// reset angle
  1276.                     solid = true;// this is outside now
  1277.                 }
  1278.             }
  1279.             pixel = (cos(r2)*d + flip(sin(r2)*d))/r + c;// compute point
  1280.         }
  1281.   
  1282.     }
  1283.     void description(void)
  1284.     {
  1285.         this.title = "Kaleidoscope";
  1286.         this.helpfile = "dmj-pub\dmj-pub-uf-kaleidoscope.htm";
  1287.  
  1288.    
  1289.         symorder.caption = "Symmetry Order";
  1290.         symorder.default = 8.0;
  1291.         symorder.hint = "Indicates the number of reflected components. Use 0 to temporarily disable symmetry.";
  1292.   
  1293.    
  1294.         symreflect.caption = "Symmetry Mode";
  1295.         symreflect.default = 0;
  1296.         symreflect.enum = "reflective\nleft\nright\nslice only";
  1297.         symreflect.hint = "Style of symmetry.  Reflective will always be seamless; left and right may not be.  If Slice is selected, only the section that will be mirrored will be shown.";
  1298.   
  1299.    
  1300.         symcenter.caption = "Symmetry Center";
  1301.         symcenter.default = (0,0);
  1302.         symcenter.hint = "Sets the center of symmetry.  If Use Screen Center is set, this item is ignored.";
  1303.   
  1304.    
  1305.         centermove.caption = "Use Screen Center";
  1306.         centermove.default = TRUE;
  1307.         centermove.hint = "If set, symmetry will be around the center of the window, regardless of the Symmetry Center setting.";
  1308.   
  1309.    
  1310.         Parm_angle.caption = "Rotation angle";
  1311.         Parm_angle.default = 0.0;
  1312.         Parm_angle.hint = "Sets how much to rotate the fractal (in degrees) before applying symmetry.";
  1313.   
  1314.     }
  1315. }
  1316.  
  1317.  
  1318. dmj-LowRes {
  1319. //
  1320. // Low Resolution Transformation
  1321. // This deliberately lowers the resolution of
  1322. // the fractal, but it does so by limiting the
  1323. // precision of complex numbers, so it is still
  1324. // usable with other transformations.
  1325. //
  1326. complex r;
  1327. parameter real Parm_angle;
  1328. parameter real xres;
  1329. parameter real yres;
  1330.  
  1331.     void transform(void)
  1332.     {
  1333.         r = (0,1) ^ (Parm_angle/90);// complex rotation vector
  1334.         pixel = (round(real(pixel*r)*xres)/xres + flip(round(imag(pixel*r)*yres)/yres)) * conj(r);
  1335.  
  1336.     }
  1337.     void description(void)
  1338.     {
  1339.         this.title = "Low Resolution";
  1340.         this.helpfile = "dmj-pub\dmj-pub-uf-lowres.htm";
  1341.  
  1342.    
  1343.         xres.caption = "Real Resolution";
  1344.         xres.default = 25.0;
  1345.         xres.hint = "Number of separate positions per horizontal unit distance.";
  1346.   
  1347.    
  1348.         yres.caption = "Imaginary Resolution";
  1349.         yres.default = 25.0;
  1350.         yres.hint = "Number of separate positions per vertical unit distance.";
  1351.   
  1352.    
  1353.         Parm_angle.caption = "Rotation angle";
  1354.         Parm_angle.default = 0.0;
  1355.         Parm_angle.hint = "Sets the angle at which the low-resolution grid is applied.";
  1356.   
  1357.     }
  1358. }
  1359.  
  1360.  
  1361. dmj-Mandelbrot {
  1362. //
  1363. // This does a few M-set iterations to warp
  1364. // the fractal shape. Try using it with a
  1365. // Newton fractal.
  1366. //
  1367. int i;
  1368. parameter real iters;
  1369. parameter complex start;
  1370. parameter real bailout;
  1371. parameter complex power;
  1372. parameter complex offset;
  1373.  
  1374.     void transform(void)
  1375.     {
  1376.         i = iters;
  1377.         z = start;
  1378.         while  ((i > 0 && |z| <= bailout))
  1379.         {
  1380.             z = z^power + pixel-offset;
  1381.             i = i - 1;
  1382.         }
  1383.         if  ((|z| > bailout))
  1384.         {
  1385.             solid = true;
  1386.         }
  1387.         else
  1388.         {
  1389.  
  1390.             pixel = z+offset;
  1391.         }
  1392.  
  1393.     }
  1394.     void description(void)
  1395.     {
  1396.         this.title = "Mandelbrot";
  1397.         this.helpfile = "dmj-pub\dmj-pub-uf-mjpnx.htm";
  1398.  
  1399.    
  1400.         iters.caption = "Iterations";
  1401.         iters.default = 4;
  1402.         iters.hint = "Number of iterations to do before calculating the fractal. Use a small number.";
  1403.   
  1404.    
  1405.         offset.caption = "Offset";
  1406.         offset.default = (0,0);
  1407.         offset.hint = "Offsets the Mandelbrot distortion.";
  1408.   
  1409.    
  1410.         start.caption = "Start Value";
  1411.         start.default = (0,0);
  1412.         start.hint = "Starting value for each point.  You can use this to 'perturb' the fractal.";
  1413.   
  1414.    
  1415.         power.caption = "Exponent";
  1416.         power.default = (2,0);
  1417.         power.hint = "Overall exponent for the equation.  (2,0) gives the classic Mandelbrot type.";
  1418.   
  1419.    
  1420.         bailout.caption = "Bailout";
  1421.         bailout.default = 1.0e20;
  1422.         bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Mandelbrot set anymore. Bailed-out points will be solid-colored.";
  1423.   
  1424.     }
  1425. }
  1426.  
  1427.  
  1428. dmj-Mirror {
  1429. //
  1430. // This transform can be used to reflect a layer
  1431. // around any arbitrary axis.
  1432. //
  1433. complex center2;
  1434. parameter complex refcenter;
  1435. parameter bool centermove;
  1436. complex r;
  1437. parameter real Parm_angle;
  1438.  
  1439.     void transform(void)
  1440.     {
  1441.         center2 = refcenter;
  1442.         if  ((centermove))
  1443.         {
  1444.             center2 = center;
  1445.         }
  1446.         r = (0,1) ^ (Parm_angle / 90.0);
  1447.         pixel = (pixel-center2) * r;
  1448.         pixel = conj(pixel);
  1449.         pixel = pixel * conj(r) + center2;
  1450.   
  1451.     }
  1452.     void description(void)
  1453.     {
  1454.         this.title = "Mirror";
  1455.         this.helpfile = "dmj-pub\dmj-pub-uf-mirror.htm";
  1456.   
  1457.    
  1458.         Parm_angle.caption = "Reflection Angle";
  1459.         Parm_angle.default = 0.0;
  1460.         Parm_angle.hint = "This is the angle for the axis of reflection.";
  1461.   
  1462.    
  1463.         refcenter.caption = "Reflection Center";
  1464.         refcenter.default = (0,0);
  1465.         refcenter.hint = "Sets the center of reflection.  Use the eyedropper to pick it.";
  1466.   
  1467.    
  1468.         centermove.caption = "Use Screen Center";
  1469.         centermove.default = TRUE;
  1470.         centermove.hint = "If set, reflection is assumed to be at the center of the window, regardless of the Reflection Center setting.";
  1471.   
  1472.     }
  1473. }
  1474.  
  1475.  
  1476. dmj-Mosaic {
  1477. //
  1478. // This transform can be used to break an image into
  1479. // many mosaic pieces, and either have those solid-
  1480. // colored or contain pieces of the fractal itself.
  1481. //
  1482. // In general you want to use as few tiles as you can
  1483. // get away with. This is because the entire set of
  1484. // tiles must be generated from scratch for *each
  1485. // pixel*. If you ask for 25,000 tiles, then the
  1486. // formula must calculate 25,000 tiles before it can
  1487. // even begin to calculate your fractal. Try to keep
  1488. // the number of tiles under 500 if you can!
  1489. //
  1490. complex center2;
  1491. parameter complex moscenter;
  1492. parameter bool centermove;
  1493. int i;
  1494. real d;
  1495. real closest1;
  1496. complex e20;
  1497. real closest2;
  1498. real random1;
  1499. parameter real seed1;
  1500. real random2;
  1501. parameter real seed2;
  1502. real random3;
  1503. parameter real seed3;
  1504. complex p;
  1505. complex point1;
  1506. complex point2;
  1507. real r1;
  1508. real range;
  1509. parameter real mostiles;
  1510. parameter real mosangle;
  1511. parameter real mosscale;
  1512. parameter int usesolid;
  1513. parameter real tileseams;
  1514. parameter real mosforce;
  1515. parameter real tilescale;
  1516.  
  1517.     void transform(void)
  1518.     {
  1519.         center2 = moscenter;
  1520.         if  ((centermove))
  1521.         {
  1522.             center2 = center;
  1523.         }
  1524.   
  1525.         i = 0;
  1526.         d = 0;
  1527.         closest1 = 1e20;
  1528.         closest2 = 1e20;
  1529.         random1 = seed1;
  1530.         random2 = seed2;
  1531.         random3 = seed3;
  1532.         p = 0;
  1533.         point1 = 0;
  1534.         point2 = 0;
  1535.         r1 = 0;
  1536.         range = 1.0 / 2147483648.0;
  1537.  
  1538.         while  ((i < mostiles))
  1539.         {// still another tile to check
  1540.             random1 = (random1 * 1103515245 + 12345) % 2147483648.0;
  1541.             random2 = (random2 * 1103515245 + 12345) % 2147483648.0;
  1542.             if  ((mosangle != 0.0))
  1543.             {
  1544.                 random3 = (random3 * 1103515245 + 12345) % 2147483648.0;
  1545.             }
  1546.             p = center2 + ((random1 - 1073741824) + flip(random2 - 1073741824)) * range * mosscale;
  1547.             d = |p - pixel|;
  1548.  
  1549.             if  ((usesolid > 0 && tileseams > 0.0))
  1550.             {
  1551.                 if  ((d < closest1))
  1552.                 {
  1553.                     closest2 = closest1;
  1554.                     point2 = point1;
  1555.                     closest1 = d;
  1556.                     point1 = p;
  1557.                     if  ((mosangle != 0.0))
  1558.                     {
  1559.                         r1 = random3;
  1560.                     }
  1561.                 }
  1562.                 else if  ((d < closest2))
  1563.                 {
  1564.                     closest2 = d;
  1565.                     point2 = p;
  1566.                 }
  1567.  
  1568.             }
  1569.             else
  1570.             {
  1571.  
  1572.                 if  ((d < closest1))
  1573.                 {
  1574.                     closest1 = d;
  1575.                     point1 = p;
  1576.                     if  ((mosangle != 0.0))
  1577.                     {
  1578.                         r1 = random3;
  1579.                     }
  1580.                 }
  1581.             }
  1582.             i = i + 1;
  1583.         }
  1584.  
  1585.         if  ((usesolid == 1 && tileseams > 0.0))
  1586.         {
  1587.             d = real((pixel-(point2+point1)*0.5) * conj(point2-point1)/cabs(point2-point1));
  1588.             if  ((abs(d) < tileseams))
  1589.             {
  1590.                 solid = true;
  1591.             }
  1592.         }
  1593.         else if  ((usesolid == 2 && tileseams > 0.0))
  1594.         {
  1595.             d = real((pixel-(point2+point1)*0.5) * conj(point2-point1)/cabs(point2-point1));
  1596.             if  ((abs(d) > tileseams))
  1597.             {
  1598.                 solid = true;
  1599.             }
  1600.         }
  1601.         else if  ((usesolid == 3 && tileseams > 0.0))
  1602.         {
  1603.             closest1 = sqrt(closest1);
  1604.             closest2 = sqrt(closest2);
  1605.             if  ((closest2-closest1 < tileseams))
  1606.             {
  1607.                 solid = true;
  1608.             }
  1609.         }
  1610.         else if  ((usesolid == 4 && tileseams > 0.0))
  1611.         {
  1612.             closest1 = sqrt(closest1);
  1613.             closest2 = sqrt(closest2);
  1614.             if  ((closest2-closest1 > tileseams))
  1615.             {
  1616.                 solid = true;
  1617.             }
  1618.         }
  1619.  
  1620.         if  ((mosangle != 0.0))
  1621.         {
  1622.             r1 = (r1 - 1073741824) * range;
  1623.         }
  1624.         pixel = point1*(1-mosforce) + (pixel-point1)*tilescale * (0,1)^(r1*mosangle/90.0);
  1625.   
  1626.     }
  1627.     void description(void)
  1628.     {
  1629.         this.title = "Mosaic";
  1630.         this.helpfile = "dmj-pub\dmj-pub-uf-mosaic.htm";
  1631.   
  1632.    
  1633.         mostiles.caption = "Number of Tiles";
  1634.         mostiles.default = 500;
  1635.         mostiles.hint = "Sets the number of mosaic tiles. More tiles take longer to render.";
  1636.   
  1637.    
  1638.         moscenter.caption = "Tiled Area Center";
  1639.         moscenter.default = (0,0);
  1640.         moscenter.hint = "Sets the center of the tiled area. The cluster of tiles will be centered at this point.";
  1641.   
  1642.    
  1643.         centermove.caption = "Use Screen Center";
  1644.         centermove.default = TRUE;
  1645.         centermove.hint = "If set, the tiled area center is assumed to be at the center of the window, regardless of the Tiled Area Center setting.";
  1646.   
  1647.    
  1648.         mosscale.caption = "Tile Density";
  1649.         mosscale.default = 5.0;
  1650.         mosscale.hint = "Specifies the overall scale of the tiles. Smaller numbers will pack the tiles together more closely.";
  1651.   
  1652.    
  1653.         tilescale.caption = "Tile Magnification";
  1654.         tilescale.default = 0.0;
  1655.         tilescale.hint = "Specifies the scale of the image within each tile. Use 0 for solid-color tiles, use 1 for no effect.";
  1656.   
  1657.    
  1658.         tileseams.caption = "Seam Width";
  1659.         tileseams.default = 0.0;
  1660.         tileseams.hint = "Sets the width of seams between tiles. If set to 0, then no seam will be calculated (faster).";
  1661.   
  1662.    
  1663.         usesolid.caption = "Solid Color Use";
  1664.         usesolid.default = 0;
  1665.         usesolid.enum = "none\nseams, no gaps\ntiles, no gaps\nseams, with gaps\ntiles, with gaps";
  1666.         usesolid.hint = "Sets what the solid color will be used for.";
  1667.   
  1668.    
  1669.         mosforce.caption = "Force Tiles to Origin";
  1670.         mosforce.default = 0.0;
  1671.         mosforce.hint = "Forces the center of each tile towards the origin. If zero, has no effect (tiles are centered normally). If one, tiles are fully moved towards the origin.";
  1672.   
  1673.    
  1674.         mosangle.caption = "Rotation Range";
  1675.         mosangle.default = 0.0;
  1676.         mosangle.hint = "Sets the range on rotations for each tile.";
  1677.   
  1678.    
  1679.         seed1.caption = "Random Seed 1";
  1680.         seed1.default = 51853571;
  1681.         seed1.hint = "This is the 'seed' for the random number generator for horizontal positions.";
  1682.   
  1683.    
  1684.         seed2.caption = "Random Seed 2";
  1685.         seed2.default = 8072177;
  1686.         seed2.hint = "This is the 'seed' for the random number generator for vertical positions.";
  1687.   
  1688.    
  1689.         seed3.caption = "Random Seed 3";
  1690.         seed3.default = 654187327;
  1691.         seed3.hint = "This is the 'seed' for the random number generator for rotations.";
  1692.   
  1693.     }
  1694. }
  1695.  
  1696.  
  1697. dmj-NovaJulia {
  1698. //
  1699. // This does a few Nova Julia iterations to warp
  1700. // the fractal shape. Try using it with a
  1701. // Newton fractal.
  1702. //
  1703. complex zsquared;
  1704. complex zcubed;
  1705. complex zold;
  1706. int i;
  1707. parameter real iters;
  1708. parameter complex offset;
  1709. parameter real bailout;
  1710. parameter complex power;
  1711. parameter complex seed;
  1712.  
  1713.     void transform(void)
  1714.     {
  1715.         zsquared = (0,0);
  1716.         zcubed = (0,0);
  1717.         zold = (0,0);
  1718.  
  1719.         i = iters;
  1720.         z = pixel-offset;
  1721.         while  ((i > 0 && |z-zold| > bailout))
  1722.         {
  1723.             if  ((power == (3,0)))
  1724.             {// special optimized routine for power 3
  1725.                 zsquared = sqr(z);
  1726.                 zcubed = zsquared * z;
  1727.                 zold = z;
  1728.                 z = z - (zcubed-1) / (3*zsquared) + seed;
  1729.             }
  1730.             else
  1731.             {
  1732.  
  1733.                 zold = z;
  1734.                 z = z - (z^power-1) / (power * z^(power-1)) + seed;
  1735.             }
  1736.             i = i - 1;
  1737.         }
  1738.         if  ((|z-zold| <= bailout))
  1739.         {
  1740.             solid = true;
  1741.         }
  1742.         else
  1743.         {
  1744.  
  1745.             pixel = z+offset;
  1746.         }
  1747.  
  1748.     }
  1749.     void description(void)
  1750.     {
  1751.         this.title = "Nova (Julia)";
  1752.         this.helpfile = "dmj-pub\dmj-pub-uf-mjpnx.htm";
  1753.  
  1754.    
  1755.         iters.caption = "Iterations";
  1756.         iters.default = 4;
  1757.         iters.hint = "Number of iterations to do before calculating the fractal. Use a small number.";
  1758.   
  1759.    
  1760.         offset.caption = "Offset";
  1761.         offset.default = (0,0);
  1762.         offset.hint = "Offsets the Nova Julia distortion.";
  1763.   
  1764.    
  1765.         seed.caption = "Julia Seed";
  1766.         seed.default = (0,0);
  1767.         seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
  1768.   
  1769.    
  1770.         power.caption = "Exponent";
  1771.         power.default = (3,0);
  1772.         power.hint = "Overall exponent for the equation.  (3,0) gives the classic Nova type.";
  1773.   
  1774.    
  1775.         bailout.caption = "Bailout";
  1776.         bailout.default = 0.00001;
  1777.         bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Nova Julia set anymore. Bailed-out points will be solid-colored.";
  1778.   
  1779.     }
  1780. }
  1781.  
  1782.  
  1783. dmj-Offset {
  1784. //
  1785. // This transform offsets the fractal with rectangular
  1786. // displacement. By itself, it accomplishes nothing that
  1787. // cannot be done better by repositioning the fractal.
  1788. // However, combined with other transforms it can produce
  1789. // some interesting distortions, and it can also be a
  1790. // convenience when creating multi-layer fractals.
  1791. //
  1792. complex offset;
  1793. parameter complex offvector;
  1794. parameter real offscale;
  1795. parameter real offangle;
  1796.  
  1797.     void transform(void)
  1798.     {
  1799.         offset = offvector * offscale * ((0,1) ^ (offangle / 90.0));
  1800.         pixel = pixel + offset;
  1801.   
  1802.     }
  1803.     void description(void)
  1804.     {
  1805.         this.title = "Offset";
  1806.         this.helpfile = "dmj-pub\dmj-pub-uf-offset.htm";
  1807.   
  1808.    
  1809.         offvector.caption = "Offset Amount";
  1810.         offvector.default = (0,0);
  1811.         offvector.hint = "Specifies the amount of offset.";
  1812.   
  1813.    
  1814.         offangle.caption = "Offset Angle";
  1815.         offangle.default = 0.0;
  1816.         offangle.hint = "Angle of offset. You can use this to rotate the offset without having to calculate the rotated offset yourself.";
  1817.   
  1818.    
  1819.         offscale.caption = "Offset Scale";
  1820.         offscale.default = 1.0;
  1821.         offscale.hint = "Scale of offset. You can use this to scale the offset without having to calculate the scaled offset yourself.";
  1822.   
  1823.     }
  1824. }
  1825.  
  1826.  
  1827. dmj-PhoenixJulia {
  1828. //
  1829. // This does a few Phoenix Julia iterations to warp
  1830. // the fractal shape. Try using it with a
  1831. // Newton fractal.
  1832. //
  1833. complex Var_y;
  1834. complex newz;
  1835. int i;
  1836. parameter real iters;
  1837. parameter complex offset;
  1838. parameter real bailout;
  1839. parameter complex power1;
  1840. parameter complex power2;
  1841. parameter complex seed;
  1842. parameter complex induct;
  1843.  
  1844.     void transform(void)
  1845.     {
  1846.         Var_y = (0,0);
  1847.         newz = (0,0);
  1848.  
  1849.         i = iters;
  1850.         z = pixel-offset;
  1851.         while  ((i > 0 && |z| <= bailout))
  1852.         {
  1853.             newz = z^power1  +  z^power2 * seed  +  induct * Var_y;
  1854.             Var_y = z;
  1855.             z = newz;
  1856.             i = i - 1;
  1857.         }
  1858.         if  ((|z| > bailout))
  1859.         {
  1860.             solid = true;
  1861.         }
  1862.         else
  1863.         {
  1864.  
  1865.             pixel = z+offset;
  1866.         }
  1867.  
  1868.     }
  1869.     void description(void)
  1870.     {
  1871.         this.title = "Phoenix (Julia)";
  1872.         this.helpfile = "dmj-pub\dmj-pub-uf-mjpnx.htm";
  1873.  
  1874.    
  1875.         iters.caption = "Iterations";
  1876.         iters.default = 4;
  1877.         iters.hint = "Number of iterations to do before calculating the fractal. Use a small number.";
  1878.   
  1879.    
  1880.         offset.caption = "Offset";
  1881.         offset.default = (0,0);
  1882.         offset.hint = "Offsets the Phoenix Julia distortion.";
  1883.   
  1884.    
  1885.         seed.caption = "Julia Seed";
  1886.         seed.default = (0.56667,0);
  1887.         seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
  1888.   
  1889.    
  1890.         power1.caption = "Primary Exponent";
  1891.         power1.default = (2,0);
  1892.         power1.hint = "Defines the primary exponent for the fractal.  The classic Phoenix curve uses exponent 2.";
  1893.   
  1894.    
  1895.         power2.caption = "Secondary Exponent";
  1896.         power2.default = (0,0);
  1897.         power2.hint = "Defines the secondary exponent for the fractal.  The classic Phoenix curve uses exponent 0.";
  1898.   
  1899.    
  1900.         induct.caption = "Phoenix Distortion";
  1901.         induct.default = (-0.5,0);
  1902.         induct.hint = "Sets how 'strong' the previous iteration's effect should be on the fractal.";
  1903.   
  1904.    
  1905.         bailout.caption = "Bailout";
  1906.         bailout.default = 1.0e20;
  1907.         bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Phoenix set anymore. Bailed-out points will be solid-colored.";
  1908.   
  1909.     }
  1910. }
  1911.  
  1912.  
  1913. dmj-Polar {
  1914. //
  1915. // This transform takes the current pixel, assumes real(pixel)
  1916. // is the angle, and imag(pixel) is the distance, and converts
  1917. // these back to the rectangular coordinates the UF expects.
  1918. // This can be used to undo the effects of the Rectangular to
  1919. // Polar transform. It can also be used to warp the heck out of
  1920. // your fractal. :)
  1921. //
  1922. parameter complex polcenter;
  1923.  
  1924.     void transform(void)
  1925.     {
  1926.         pixel = real(pixel)*cos(imag(pixel)) + flip(real(pixel)*sin(imag(pixel))) + polcenter;
  1927.  
  1928.     }
  1929.     void description(void)
  1930.     {
  1931.         this.title = "Polar to Rectangular";
  1932.         this.helpfile = "dmj-pub\dmj-pub-uf-p2r.htm";
  1933.   
  1934.    
  1935.         polcenter.caption = "Polar Center";
  1936.         polcenter.default = (0,0);
  1937.         polcenter.hint = "This is the center of the polar coordinate system.";
  1938.   
  1939.     }
  1940. }
  1941.  
  1942.  
  1943. dmj-SelectJulia {
  1944. //
  1945. // This formula "selects" a portion of the image,
  1946. // based on the iteration count for the Julia set at
  1947. // each pixel.
  1948. //
  1949. real b;
  1950. parameter real bailout;
  1951. parameter bool strict;
  1952. parameter complex seed;
  1953. int i;
  1954. parameter real Parm_maxiter;
  1955. parameter complex power;
  1956. real r;
  1957. parameter real divisor;
  1958. parameter real remainder;
  1959. parameter real Parm_width;
  1960.  
  1961.     void transform(void)
  1962.     {
  1963.         z = pixel;
  1964.         b = bailout;
  1965.         if  ((strict))
  1966.         {
  1967.             b = sqr(1+sqrt(1+4*cabs(seed)))*0.25;
  1968.         }
  1969.         i = 0;
  1970.  
  1971.         while  ((|z| < b && i < Parm_maxiter))
  1972.         {
  1973.             z = z^power + seed;
  1974.             i = i + 1;
  1975.         }
  1976.  
  1977.         r = real(xfer(flip(flip(i))));
  1978.         r = r - trunc(r / divisor) * divisor;
  1979.         if  ((r < remainder || r >= remainder+Parm_width))
  1980.         {
  1981.             solid = true;
  1982.         }
  1983.  
  1984.     }
  1985.     void description(void)
  1986.     {
  1987.         this.title = "Select (Julia)";
  1988.         this.helpfile = "dmj-pub\dmj-pub-uf-select.htm";
  1989.  
  1990.    
  1991.         Parm_maxiter.caption = "Maximum Iterations";
  1992.         Parm_maxiter.default = 150;
  1993.         Parm_maxiter.hint = "Maximum number of iterations that will be performed for the transform.";
  1994.   
  1995.    
  1996.         seed.caption = "Julia Seed";
  1997.         seed.default = (0,0);
  1998.         seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
  1999.   
  2000.    
  2001.         power.caption = "Exponent";
  2002.         power.default = (2,0);
  2003.         power.hint = "Overall exponent for the equation.  (2,0) gives the classic Julia type.";
  2004.   
  2005.    
  2006.         bailout.caption = "Bailout";
  2007.         bailout.default = 128;
  2008.         bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Mandelbrot set anymore.";
  2009.   
  2010.    
  2011.         strict.caption = "Strict Bailout";
  2012.         strict.default = FALSE;
  2013.         strict.hint = "If set, uses 'strict' bailout checking, which varies the bailout value with each point. This will override the Bailout parameter.";
  2014.   
  2015.    
  2016.         divisor.caption = "Iteration Divisor";
  2017.         divisor.default = 2.0;
  2018.         divisor.hint = "The iteration count will be divided by this value, and the remainder taken.";
  2019.   
  2020.    
  2021.         remainder.caption = "Iteration Remainder";
  2022.         remainder.default = 1.0;
  2023.         remainder.hint = "If the remainder after dividing the iteration count does not match this value, the pixel will be colored 'solid'.";
  2024.   
  2025.    
  2026.         Parm_width.caption = "Band Width";
  2027.         Parm_width.default = 1.0;
  2028.         Parm_width.hint = "The width of the non-solid band, in iterations.";
  2029.   
  2030.    
  2031.         xfer.caption = "Iteration Transfer";
  2032.         xfer.default = "ident" ;
  2033.         xfer.hint = "This function will be applied to the iteration count before it is divided.";
  2034.   
  2035.     }
  2036. }
  2037.  
  2038.  
  2039. dmj-SelectMandel {
  2040. //
  2041. // This formula "selects" a portion of the image,
  2042. // based on the iteration count for the M-set at each
  2043. // pixel.
  2044. //
  2045. parameter complex start;
  2046. real b;
  2047. parameter real bailout;
  2048. parameter bool strict;
  2049. int i;
  2050. parameter real Parm_maxiter;
  2051. parameter complex power;
  2052. real r;
  2053. parameter real divisor;
  2054. parameter real remainder;
  2055. parameter real Parm_width;
  2056.  
  2057.     void transform(void)
  2058.     {
  2059.         z = start;
  2060.         b = bailout;
  2061.         if  ((strict))
  2062.         {
  2063.             b = sqr(1+sqrt(1+4*cabs(pixel)))*0.25;
  2064.         }
  2065.         i = 0;
  2066.  
  2067.         while  ((|z| < b && i < Parm_maxiter))
  2068.         {
  2069.             z = z^power + pixel;
  2070.             i = i + 1;
  2071.         }
  2072.  
  2073.         r = real(xfer(flip(flip(i))));
  2074.         r = r - trunc(r / divisor) * divisor;
  2075.         if  ((r < remainder || r >= remainder+Parm_width))
  2076.         {
  2077.             solid = true;
  2078.         }
  2079.   
  2080.     }
  2081.     void description(void)
  2082.     {
  2083.         this.title = "Select (Mandelbrot)";
  2084.         this.helpfile = "dmj-pub\dmj-pub-uf-select.htm";
  2085.  
  2086.    
  2087.         Parm_maxiter.caption = "Maximum Iterations";
  2088.         Parm_maxiter.default = 150;
  2089.         Parm_maxiter.hint = "Maximum number of iterations that will be performed for the transform.";
  2090.   
  2091.    
  2092.         start.caption = "Start Value";
  2093.         start.default = (0,0);
  2094.         start.hint = "Starting value for each point.  You can use this to 'perturb' the fractal.";
  2095.   
  2096.    
  2097.         power.caption = "Exponent";
  2098.         power.default = (2,0);
  2099.         power.hint = "Overall exponent for the equation.  (2,0) gives the classic Mandelbrot type.";
  2100.   
  2101.    
  2102.         bailout.caption = "Bailout";
  2103.         bailout.default = 128;
  2104.         bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Mandelbrot set anymore.";
  2105.   
  2106.    
  2107.         strict.caption = "Strict Bailout";
  2108.         strict.default = FALSE;
  2109.         strict.hint = "If set, uses 'strict' bailout checking, which varies the bailout value with each point. This will override the Bailout parameter.";
  2110.   
  2111.    
  2112.         divisor.caption = "Iteration Divisor";
  2113.         divisor.default = 2.0;
  2114.         divisor.hint = "The iteration count will be divided by this value, and the remainder taken.";
  2115.   
  2116.    
  2117.         remainder.caption = "Iteration Remainder";
  2118.         remainder.default = 1.0;
  2119.         remainder.hint = "If the remainder after dividing the iteration count does not match this value, the pixel will be colored 'solid'.";
  2120.   
  2121.    
  2122.         Parm_width.caption = "Band Width";
  2123.         Parm_width.default = 1.0;
  2124.         Parm_width.hint = "The width of the non-solid band, in iterations.";
  2125.   
  2126.    
  2127.         xfer.caption = "Iteration Transfer";
  2128.         xfer.default = "ident" ;
  2129.         xfer.hint = "This function will be applied to the iteration count before it is divided.";
  2130.   
  2131.     }
  2132. }
  2133.  
  2134.  
  2135. dmj-SelectNovaJulia {
  2136. //
  2137. // This formula "selects" a portion of the image,
  2138. // based on the iteration count for the Nova set at
  2139. // each pixel.
  2140. //
  2141. complex zsquared;
  2142. complex zcubed;
  2143. complex zold;
  2144. int i;
  2145. parameter real bailout;
  2146. parameter real Parm_maxiter;
  2147. parameter complex power;
  2148. parameter complex seed;
  2149. real r;
  2150. parameter real divisor;
  2151. parameter real remainder;
  2152. parameter real Parm_width;
  2153.  
  2154.     void transform(void)
  2155.     {
  2156.         zsquared = (0,0);
  2157.         zcubed = (0,0);
  2158.         zold = (0,0);
  2159.  
  2160.         z = pixel;
  2161.         i = 0;
  2162.  
  2163.         while  ((|z-zold| > bailout && i < Parm_maxiter))
  2164.         {
  2165.             if  ((power == (3,0)))
  2166.             {// special optimized routine for power 3
  2167.                 zsquared = sqr(z);
  2168.                 zcubed = zsquared * z;
  2169.                 zold = z;
  2170.                 z = z - (zcubed-1) / (3*zsquared) + seed;
  2171.             }
  2172.             else
  2173.             {
  2174.  
  2175.                 zold = z;
  2176.                 z = z - (z^power-1) / (power * z^(power-1)) + seed;
  2177.             }
  2178.             i = i + 1;
  2179.         }
  2180.  
  2181.         r = real(xfer(flip(flip(i))));
  2182.         r = r - trunc(r / divisor) * divisor;
  2183.         if  ((r < remainder || r >= remainder+Parm_width))
  2184.         {
  2185.             solid = true;
  2186.         }
  2187.   
  2188.     }
  2189.     void description(void)
  2190.     {
  2191.         this.title = "Select (Nova Julia)";
  2192.         this.helpfile = "dmj-pub\dmj-pub-uf-select.htm";
  2193.  
  2194.    
  2195.         Parm_maxiter.caption = "Maximum Iterations";
  2196.         Parm_maxiter.default = 150;
  2197.         Parm_maxiter.hint = "Maximum number of iterations that will be performed for the transform.";
  2198.   
  2199.    
  2200.         seed.caption = "Julia Seed";
  2201.         seed.default = (0,0);
  2202.         seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
  2203.   
  2204.    
  2205.         power.caption = "Exponent";
  2206.         power.default = (3,0);
  2207.         power.hint = "Overall exponent for the equation.  (3,0) gives the classic Nova type.";
  2208.   
  2209.    
  2210.         bailout.caption = "Bailout";
  2211.         bailout.default = 0.00001;
  2212.         bailout.hint = "Bailout value; smaller values will cause more iterations to be done for each point.";
  2213.   
  2214.    
  2215.         divisor.caption = "Iteration Divisor";
  2216.         divisor.default = 2.0;
  2217.         divisor.hint = "The iteration count will be divided by this value, and the remainder taken.";
  2218.   
  2219.    
  2220.         remainder.caption = "Iteration Remainder";
  2221.         remainder.default = 1.0;
  2222.         remainder.hint = "If the remainder after dividing the iteration count does not match this value, the pixel will be colored 'solid'.";
  2223.   
  2224.    
  2225.         Parm_width.caption = "Band Width";
  2226.         Parm_width.default = 1.0;
  2227.         Parm_width.hint = "The width of the non-solid band, in iterations.";
  2228.   
  2229.    
  2230.         xfer.caption = "Iteration Transfer";
  2231.         xfer.default = "ident" ;
  2232.         xfer.hint = "This function will be applied to the iteration count before it is divided.";
  2233.   
  2234.     }
  2235. }
  2236.  
  2237.  
  2238. dmj-SelectPhoenixJulia {
  2239. //
  2240. // This formula "selects" a portion of the image,
  2241. // based on the iteration count for the Phoenix set
  2242. // at each pixel.
  2243. //
  2244. complex Var_y;
  2245. complex newz;
  2246. int i;
  2247. parameter real bailout;
  2248. parameter real Parm_maxiter;
  2249. parameter complex power1;
  2250. parameter complex power2;
  2251. parameter complex seed;
  2252. parameter complex induct;
  2253. real r;
  2254. parameter real divisor;
  2255. parameter real remainder;
  2256. parameter real Parm_width;
  2257.  
  2258.     void transform(void)
  2259.     {
  2260.         Var_y = (0,0);
  2261.         newz = (0,0);
  2262.  
  2263.         z = pixel;
  2264.         i = 0;
  2265.  
  2266.         while  ((|z| < bailout && i < Parm_maxiter))
  2267.         {
  2268.             newz = z^power1  +  z^power2 * seed  +  induct * Var_y;
  2269.             Var_y = z;
  2270.             z = newz;
  2271.             i = i + 1;
  2272.         }
  2273.  
  2274.         r = real(xfer(flip(flip(i))));
  2275.         r = r - trunc(r / divisor) * divisor;
  2276.         if  ((r < remainder || r >= remainder+Parm_width))
  2277.         {
  2278.             solid = true;
  2279.         }
  2280.   
  2281.     }
  2282.     void description(void)
  2283.     {
  2284.         this.title = "Select (Phoenix Julia)";
  2285.         this.helpfile = "dmj-pub\dmj-pub-uf-select.htm";
  2286.  
  2287.    
  2288.         Parm_maxiter.caption = "Maximum Iterations";
  2289.         Parm_maxiter.default = 150;
  2290.         Parm_maxiter.hint = "Maximum number of iterations that will be performed for the transform.";
  2291.   
  2292.    
  2293.         seed.caption = "Julia Seed";
  2294.         seed.default = (0.56667,0);
  2295.         seed.hint = "This is the Julia seed, a constant parameter which defines the shape of the fractal.";
  2296.   
  2297.    
  2298.         power1.caption = "Primary Exponent";
  2299.         power1.default = (2,0);
  2300.         power1.hint = "Defines the primary exponent for the fractal.  The classic Phoenix curve uses exponent 2.";
  2301.   
  2302.    
  2303.         power2.caption = "Secondary Exponent";
  2304.         power2.default = (0,0);
  2305.         power2.hint = "Defines the secondary exponent for the fractal.  The classic Phoenix curve uses exponent 0.";
  2306.   
  2307.    
  2308.         induct.caption = "Phoenix Distortion";
  2309.         induct.default = (-0.5,0);
  2310.         induct.hint = "Sets how 'strong' the previous iteration's effect should be on the fractal.";
  2311.   
  2312.    
  2313.         bailout.caption = "Bailout";
  2314.         bailout.default = 1.0e20;
  2315.         bailout.hint = "Defines how soon an orbit bails out, i.e. doesn't belong to the Phoenix set anymore.";
  2316.   
  2317.    
  2318.         divisor.caption = "Iteration Divisor";
  2319.         divisor.default = 2.0;
  2320.         divisor.hint = "The iteration count will be divided by this value, and the remainder taken.";
  2321.   
  2322.    
  2323.         remainder.caption = "Iteration Remainder";
  2324.         remainder.default = 1.0;
  2325.         remainder.hint = "If the remainder after dividing the iteration count does not match this value, the pixel will be colored 'solid'.";
  2326.   
  2327.    
  2328.         Parm_width.caption = "Band Width";
  2329.         Parm_width.default = 1.0;
  2330.         Parm_width.hint = "The width of the non-solid band, in iterations.";
  2331.   
  2332.    
  2333.         xfer.caption = "Iteration Transfer";
  2334.         xfer.default = "ident" ;
  2335.         xfer.hint = "This function will be applied to the iteration count before it is divided.";
  2336.   
  2337.     }
  2338. }
  2339.  
  2340.  
  2341. dmj-SpiralCut {
  2342. //
  2343. // This transformation cuts your image into several slices,
  2344. // and then inflates the size of each slice independently.
  2345. // I got the idea for this from an old Photoshop plug-in.
  2346. //
  2347. complex center2;
  2348. parameter complex cutcenter;
  2349. parameter bool centermove;
  2350. complex r;
  2351. parameter real Parm_angle;
  2352. complex p0;
  2353. complex p;
  2354. real a;
  2355. real d;
  2356. parameter int mode;
  2357. parameter real density;
  2358. parameter real boost;
  2359.  
  2360.     void transform(void)
  2361.     {
  2362.         center2 = cutcenter;
  2363.         if  ((centermove))
  2364.         {
  2365.             center2 = center;
  2366.         }
  2367.         r = (0,1) ^ (Parm_angle / 90.0);
  2368.         p0 = (pixel-center2)*r;
  2369.         p = p0;
  2370.         a = atan2(p0);
  2371.         d = cabs(p0);
  2372.  
  2373.         if  ((mode == 0))
  2374.         {
  2375.             d = round(d*density)/density;
  2376.         }
  2377.         else if  ((mode == 1))
  2378.         {
  2379.             a = round(a*density)/density;
  2380.         }
  2381.         else if  ((mode == 2))
  2382.         {
  2383.             d = round(d*density)/density;
  2384.             a = round(a*density)/density;
  2385.         }
  2386.         else if  ((mode == 3))
  2387.         {
  2388.             p = round(real(p)*density)/density + flip(imag(p));
  2389.         }
  2390.         else if  ((mode == 4))
  2391.         {
  2392.             p = round(real(p)*density)/density + flip(round(imag(p)*density)/density);
  2393.         }
  2394.         if  ((mode < 3))
  2395.         {
  2396.             p = d * (cos(a) + flip(sin(a)));
  2397.         }
  2398.         pixel = (p + (p0-p)*boost) * conj(r) + center2;
  2399.     
  2400.     }
  2401.     void description(void)
  2402.     {
  2403.         this.title = "Spiral Cut";
  2404.         this.helpfile = "dmj-pub\dmj-pub-uf-spiralcut.htm";
  2405.   
  2406.    
  2407.         mode.caption = "Cut Mode";
  2408.         mode.default = 0;
  2409.         mode.enum = "rings\nrays\nradial grid\nlines\ngrid";
  2410.   
  2411. //  param nodistort
  2412. //    caption = "No Squashing"
  2413. //    default = true
  2414. //  endparam
  2415.    
  2416.         density.caption = "Cut Density";
  2417.         density.default = 5.0;
  2418.   
  2419.    
  2420.         Parm_angle.caption = "Cut Angle";
  2421.         Parm_angle.default = 0.0;
  2422.   
  2423.    
  2424.         boost.caption = "Cut Exaggeration";
  2425.         boost.default = 2.0;
  2426.   
  2427.    
  2428.         cutcenter.caption = "Cut Center";
  2429.         cutcenter.default = (0,0);
  2430.         cutcenter.hint = "Sets the center of the cut pattern.  Use the eyedropper to pick it.";
  2431.   
  2432.    
  2433.         centermove.caption = "Use Screen Center";
  2434.         centermove.default = TRUE;
  2435.         centermove.hint = "If set, the cut pattern is assumed to be at the center of the window, regardless of the Cut Center setting.";
  2436.   
  2437.     }
  2438. }
  2439.  
  2440.  
  2441. dmj-Spots {
  2442. //
  2443. // This uses to mosaic tile placement algorithm to choose
  2444. // "spots" to paint the image with. However, once a spot is
  2445. // found to cover a pixel, the remaining spots are not
  2446. // calculated. The overall effect is one of pointillist
  2447. // fractals.
  2448. //
  2449. complex center2;
  2450. parameter complex moscenter;
  2451. parameter bool centermove;
  2452. int i;
  2453. real d;
  2454. real random1;
  2455. parameter real seed1;
  2456. real random2;
  2457. parameter real seed2;
  2458. real random3;
  2459. parameter real seed3;
  2460. complex p;
  2461. complex point1;
  2462. real r1;
  2463. real range;
  2464. parameter real mostiles;
  2465. parameter real mosscale;
  2466. parameter real mosmax;
  2467. parameter real mosmin;
  2468. parameter bool usesolid;
  2469. parameter real tilescale;
  2470.  
  2471.     void transform(void)
  2472.     {
  2473.         center2 = moscenter;
  2474.         if  ((centermove))
  2475.         {
  2476.             center2 = center;
  2477.         }
  2478.   
  2479.         i = 0;
  2480.         d = 0;
  2481.         random1 = seed1;
  2482.         random2 = seed2;
  2483.         random3 = seed3;
  2484.         p = 0;
  2485.         point1 = 0;
  2486.         r1 = 0;
  2487.         range = 1.0 / 2147483648.0;
  2488.  
  2489.         while  ((i < mostiles))
  2490.         {// still another tile to check
  2491.             random1 = (random1 * 1103515245 + 12345) % 2147483648.0;
  2492.             random2 = (random2 * 1103515245 + 12345) % 2147483648.0;
  2493.             random3 = (random3 * 1103515245 + 12345) % 2147483648.0;
  2494.             p = center2 + ((random1 - 1073741824) + flip(random2 - 1073741824)) * range * mosscale;
  2495.             d = |p - pixel|;
  2496.             r1 = (random3 * range) * (mosmax-mosmin) + mosmin;
  2497.  
  2498.             if  ((d < r1))
  2499.             {
  2500.                 point1 = p;
  2501.                 i = mostiles;
  2502.             }
  2503.             i = i + 1;
  2504.         }
  2505.  
  2506.         if  ((i == mostiles))
  2507.         {
  2508.             if  ((usesolid))
  2509.             {
  2510.                 solid = true;
  2511.             }
  2512.         }
  2513.         else
  2514.         {
  2515.  
  2516.             pixel = point1 + (pixel-point1)*tilescale;
  2517.         }
  2518.   
  2519.     }
  2520.     void description(void)
  2521.     {
  2522.         this.title = "Spots";
  2523.         this.helpfile = "dmj-pub\dmj-pub-uf-spots.htm";
  2524.   
  2525.    
  2526.         mostiles.caption = "Number of Spots";
  2527.         mostiles.default = 500;
  2528.         mostiles.hint = "Sets the number of spots. More spots take longer to render.";
  2529.   
  2530.    
  2531.         moscenter.caption = "Spotted Area Center";
  2532.         moscenter.default = (0,0);
  2533.         moscenter.hint = "Sets the center of the spotted area. The cluster of spots will be centered at this point.";
  2534.   
  2535.    
  2536.         centermove.caption = "Use Screen Center";
  2537.         centermove.default = TRUE;
  2538.         centermove.hint = "If set, the spotted area center is assumed to be at the center of the window, regardless of the Spotted Area Center setting.";
  2539.   
  2540.    
  2541.         mosscale.caption = "Spot Density";
  2542.         mosscale.default = 5.0;
  2543.         mosscale.hint = "Specifies the overall scale of the spots. Smaller numbers will pack the spots together more closely.";
  2544.   
  2545.    
  2546.         tilescale.caption = "Spot Magnification";
  2547.         tilescale.default = 0.0;
  2548.         tilescale.hint = "Specifies the scale of the image within each spot. Use 0 for solid-color spots, use 1 for no effect.";
  2549.   
  2550.    
  2551.         mosmin.caption = "Minimum Spot Size";
  2552.         mosmin.default = 0.01;
  2553.         mosmin.hint = "This is the minimum size a spot may be.";
  2554.   
  2555.    
  2556.         mosmax.caption = "Maximum Spot Size";
  2557.         mosmax.default = 0.1;
  2558.         mosmax.hint = "This is the maximum size a spot may be.";
  2559.   
  2560.    
  2561.         usesolid.caption = "Use Solid Color";
  2562.         usesolid.default = true;
  2563.         usesolid.hint = "If set, points outside all spots will use the solid color. Otherwise, those points are untransformed.";
  2564.   
  2565.    
  2566.         seed1.caption = "Random Seed 1";
  2567.         seed1.default = 51853571;
  2568.         seed1.hint = "This is the 'seed' for the random number generator for horizontal positions.";
  2569.   
  2570.    
  2571.         seed2.caption = "Random Seed 2";
  2572.         seed2.default = 8072177;
  2573.         seed2.hint = "This is the 'seed' for the random number generator for vertical positions.";
  2574.   
  2575.    
  2576.         seed3.caption = "Random Seed 3";
  2577.         seed3.default = 654187327;
  2578.         seed3.hint = "This is the 'seed' for the random number generator for rotations.";
  2579.   
  2580.     }
  2581. }
  2582.  
  2583.  
  2584. dmj-Stretch {
  2585. //
  2586. // Stretch transform that can use screen center.
  2587. // If you have a fractal image that you want to stretch on
  2588. // one axis only, and don't want to work out the (hairy) math
  2589. // to make the Stretch transform that comes with UF work, you
  2590. // can just apply this one. The usual caveats for zooming into
  2591. // an image with a "Use Screen Center" transform do apply,
  2592. // of course.
  2593. //
  2594. complex r;
  2595. parameter real strangle;
  2596. complex center2;
  2597. parameter complex strcenter;
  2598. parameter bool centermove;
  2599. complex z2;
  2600. parameter complex strscale;
  2601.  
  2602.     void transform(void)
  2603.     {
  2604.         r = (0,1) ^ (strangle / 90.0);
  2605.         center2 = strcenter;
  2606.         if  ((centermove))
  2607.         {
  2608.             center2 = center;
  2609.         }
  2610.         z2 = (pixel - center2) * r;
  2611.         pixel = (real(z2)*real(strscale) + flip(imag(z2)*imag(strscale))) * conj(r) + center2;
  2612.  
  2613.     }
  2614.     void description(void)
  2615.     {
  2616.         this.title = "Stretch";
  2617.         this.helpfile = "dmj-pub\dmj-pub-uf-stretch.htm";
  2618.  
  2619.    
  2620.         strcenter.caption = "Stretch Center";
  2621.         strcenter.default = (0,0);
  2622.         strcenter.hint = "Sets the center of stretching.  Use the eyedropper to pick the center of stretching.";
  2623.   
  2624.    
  2625.         centermove.caption = "Use Screen Center";
  2626.         centermove.default = TRUE;
  2627.         centermove.hint = "If set, stretching is assumed to be at the center of the window, regardless of the Stretch Center setting.";
  2628.   
  2629.    
  2630.         strscale.caption = "Stretch Scale";
  2631.         strscale.default = (1,1);
  2632.         strscale.hint = "Sets the amount of stretching on each axis. The default of (1,1) produces no stretching (normal scale).";
  2633.   
  2634.    
  2635.         strangle.caption = "Stretch Angle";
  2636.         strangle.default = 0.0;
  2637.         strangle.hint = "Sets the angle of stretching. You can use this to rotate the axes where stretching occurs.";
  2638.   
  2639.     }
  2640. }
  2641.  
  2642.  
  2643. dmj-Symmetry {
  2644. //
  2645. // Symmetry Transformation
  2646. // This is simpler (and faster) to use for basic
  2647. // symmetry than Kaleidoscope.  However, because
  2648. // the symmetry center is ALWAYS the image center,
  2649. // various surprising things may happen if you try
  2650. // to zoom on an image using this transform.
  2651. //
  2652. complex r;
  2653. complex z2;
  2654. complex c;
  2655. parameter int mode;
  2656.  
  2657.     void transform(void)
  2658.     {
  2659.         r = (0,1) ^ (angle * 2/pi);// complex rotation vector
  2660.         z2 = (0,0);
  2661.         c = center;// symmetry center is screen center
  2662.   
  2663.         if  ((mode == 0))
  2664.         {// horizontal symmetry
  2665.             if  ((x > width/2))
  2666.             {// point is in right half
  2667.                 z2 = (pixel-c) / r;// flip it
  2668.                 pixel = r * (-conj(z2)) + c;
  2669.             }
  2670.         }
  2671.         else if  ((mode == 1))
  2672.         {// vertical symmetry
  2673.             if  ((y > height/2))
  2674.             {// point is in bottom half
  2675.                 z2 = (pixel-c) / r;// flip it
  2676.                 pixel = r * (conj(z2)) + c;
  2677.             }
  2678.         }
  2679.         else if  ((mode == 2))
  2680.         {// diagonal symmetry
  2681.             if  ((x+y > (width+height)/2))
  2682.             {// point is in lower right half
  2683.                 z2 = (pixel-c) / r;// flip it
  2684.                 pixel = r * (-z2) + c;
  2685.             }
  2686.         }
  2687.         else if  ((mode == 3))
  2688.         {// horizontal + vertical symmetry
  2689.             if  ((x > width/2))
  2690.             {// point is in right half
  2691.                 z2 = (pixel-c) / r;// flip it
  2692.                 pixel = r * (-conj(z2)) + c;
  2693.             }
  2694.             if  ((y > height/2))
  2695.             {// point is in bottom half
  2696.                 z2 = (pixel-c) / r;// flip it
  2697.                 pixel = r * (conj(z2)) + c;
  2698.             }
  2699.         }
  2700.  
  2701.     }
  2702.     void description(void)
  2703.     {
  2704.         this.title = "Symmetry";
  2705.         this.helpfile = "dmj-pub\dmj-pub-uf-symmetry.htm";
  2706.   
  2707.    
  2708.         mode.caption = "Symmetry Mode";
  2709.         mode.default = 0;
  2710.         mode.enum = "horizontal\nvertical\ndiagonal\nhorz + vert\nnone";
  2711.         mode.hint = "Style of symmetry.";
  2712.   
  2713.     }
  2714. }
  2715.  
  2716.  
  2717. dmj-Triangle-Glass1 {
  2718. //
  2719. // I think I must be insane.
  2720. //
  2721. // This formula iterates the M-set and uses triangle inequality
  2722. // average coloring as a turbulence value. It is similar to fBm
  2723. // Glass 1, just with a different texture used for the turbulence.
  2724. //
  2725. // Don't try this at home, kids.
  2726. //
  2727. complex c;
  2728. complex r3;
  2729. parameter real distangle;
  2730. complex v;
  2731. parameter real mandscale;
  2732. parameter complex mandcenter;
  2733. real sum;
  2734. real sum2;
  2735. real ac;
  2736. real il;
  2737. parameter real mandpower;
  2738. real lp;
  2739. parameter real mandbailout;
  2740. real az2;
  2741. real lowbound;
  2742. real f;
  2743. bool first;
  2744. real ipower;
  2745. parameter real apower;
  2746. int i;
  2747. parameter real manditer;
  2748. parameter int aflavor;
  2749. parameter complex distcenter;
  2750. parameter bool centermove;
  2751. parameter int style;
  2752. parameter real distortion;
  2753.  
  2754.     void transform(void)
  2755.     {
  2756.         z = 0;
  2757.         c = pixel;
  2758.         r3 = (0,1) ^ (distangle / 90.0);
  2759.         v = 0;
  2760.  
  2761.   // translate/scale
  2762.         c = c/mandscale + mandcenter;
  2763.  
  2764.         sum = 0.0;
  2765.         sum2 = 0.0;
  2766.         ac = cabs(c);
  2767.         il = 1/log(mandpower);
  2768.         lp = log(log(mandbailout)/2.0);
  2769.         az2 = 0.0;
  2770.         lowbound = 0.0;
  2771.         f = 0.0;
  2772.         first = true;
  2773.         ipower = 1/apower;
  2774.   
  2775.         i = 0;
  2776.         while  ((i < manditer && |z| < mandbailout))
  2777.         {
  2778.             z = z^mandpower + c;
  2779.             i = i + 1;
  2780.  
  2781.             sum2 = sum;
  2782.             if  ((!first))
  2783.             {
  2784.                 az2 = cabs(z - c);
  2785.                 lowbound = abs(az2 - ac);
  2786.                 if  ((aflavor == 0))
  2787.                 {
  2788.                     sum = sum + ((cabs(z) - lowbound) / (az2+ac - lowbound))^apower;
  2789.                 }
  2790.                 else if  ((aflavor == 1))
  2791.                 {
  2792.                     sum = sum + 1-(1-(cabs(z) - lowbound) / (az2+ac - lowbound))^ipower;
  2793.                 }
  2794.             }
  2795.             else
  2796.             {
  2797.  
  2798.                 first = false;
  2799.             }
  2800.  
  2801.         }
  2802.   
  2803.         sum = sum / i;
  2804.         sum2 = sum2 / (i-1);
  2805.         f = il*lp - il*log(log(cabs(z)));
  2806.         f = sum2 + (sum-sum2) * (f+1);
  2807. //  f = f - floor(f)
  2808.  
  2809.         c = distcenter;
  2810.         if  ((centermove))
  2811.         {
  2812.             c = center;
  2813.         }
  2814.  
  2815.         if  ((style == 0))
  2816.         {// radial distortion
  2817.             v = (pixel-c)/cabs(pixel-c) * r3;// use vector based on angle to distortion center
  2818.         }
  2819.         else if  ((style == 1))
  2820.         {// linear distortion
  2821.             v = r3;// just use rotation vector
  2822.         }
  2823.         pixel = pixel + v * f*0.5*distortion;
  2824.  
  2825.     }
  2826.     void description(void)
  2827.     {
  2828.         this.title = "TIA Glass 1";
  2829.         this.helpfile = "dmj-pub\dmj-pub-uf-tiag1.htm";
  2830.  
  2831.    
  2832.         distortion.caption = "Distortion Strength";
  2833.         distortion.default = 1.0;
  2834.         distortion.hint = "This is the amount the noise distorts the image.";
  2835.   
  2836.    
  2837.         style.caption = "Distortion Style";
  2838.         style.default = 0;
  2839.         style.enum = "radial\nlinear";
  2840.         style.hint = "This selects whether the distortion will be focused around a single point, or directed along a line.";
  2841.   
  2842.    
  2843.         distangle.caption = "Distortion Angle";
  2844.         distangle.default = 0.0;
  2845.         distangle.hint = "This is the angle to rotate the distortion.";
  2846.   
  2847.    
  2848.         distcenter.caption = "Distortion Center";
  2849.         distcenter.default = (0,0);
  2850.         distcenter.hint = "Sets the center of distortion.  If Use Screen Center is set, this item is ignored.";
  2851.   
  2852.    
  2853.         centermove.caption = "Use Screen Center";
  2854.         centermove.default = TRUE;
  2855.         centermove.hint = "If set, distortion will be around the center of the window, regardless of the Distortion Center setting.";
  2856.   
  2857.  
  2858.    
  2859.         mandpower.caption = "Mandelbrot Power";
  2860.         mandpower.default = 2.0;
  2861.         mandpower.hint = "Overall exponent for the equation.  (2,0) gives the classic Mandelbrot type.";
  2862.   
  2863.    
  2864.         mandbailout.caption = "Mandelbrot Bailout";
  2865.         mandbailout.default = 1.0e10;
  2866.         mandbailout.hint = "Bailout value; larger values will cause more iterations to be done for each point.";
  2867.   
  2868.    
  2869.         mandcenter.caption = "Mandelbrot Center";
  2870.         mandcenter.default = (0,0);
  2871.         mandcenter.hint = "Center of Mandelbrot shape; this can be used to offset the distortion.";
  2872.   
  2873.    
  2874.         mandscale.caption = "Mandelbrot Scale";
  2875.         mandscale.default = 1.0;
  2876.         mandscale.hint = "Scale of Mandelbrot shape; this can be used to change the size of the Mandelbrot shape relative to the distorted fractal.";
  2877.   
  2878.    
  2879.         manditer.caption = "Mandelbrot Iterations";
  2880.         manditer.default = 100;
  2881.         manditer.hint = "Maximum number of Mandelbrot iterations to do.";
  2882.   
  2883.  
  2884.    
  2885.         apower.caption = "Average Exponent";
  2886.         apower.default = 1.0;
  2887.         apower.hint = "This skews the values averaged by raising them to this power. Use 1.0 for the classic coloring.";
  2888.   
  2889.    
  2890.         aflavor.caption = "Average Flavor";
  2891.         aflavor.default = 0;
  2892.         aflavor.enum = "normal\nreversed";
  2893.         aflavor.hint = "Controls whether values are reversed before being raised to a power. Has no effect if Average Exponent is 1.0.";
  2894.   
  2895. //  param power
  2896. //    caption = "Exponent"
  2897. //    default = 2.0
  2898. //    hint = "This should be set to match the exponent of the ;            formula you are using.  For Mandelbrot, this is 2."
  2899. //  endparam
  2900. //  param bailout
  2901. //    caption = "Bailout"
  2902. //    default = 1e20
  2903. //    min = 1
  2904. //    hint = "This should be set to match the bailout value in ;            the Formula tab.  Use a very high bailout!"
  2905. //  endparam
  2906.   
  2907.     }
  2908. }
  2909.  
  2910.  
  2911. dmj-Twirl {
  2912. //
  2913. // Ripple Transformation
  2914. // This transform will add ripples to a fractal.
  2915. // Add multiple transforms for interference effects.
  2916. //
  2917. complex center2;
  2918. parameter complex twirlcenter;
  2919. parameter bool centermove;
  2920. real d;
  2921. parameter real twirlfade;
  2922. parameter int twirltype;
  2923. parameter real twirlpitch;
  2924. parameter real twirlscale;
  2925. real d2;
  2926.  
  2927.     void transform(void)
  2928.     {
  2929.         center2 = twirlcenter;
  2930.         if  ((centermove))
  2931.         {
  2932.             center2 = center;
  2933.         }
  2934.         d = cabs(pixel-center2);
  2935.         if  ((d < twirlfade))
  2936.         {
  2937.             if  ((twirltype == 0))
  2938.             {// side to side
  2939.                 pixel = (pixel-center2) * (0,1) ^ (cos(d*twirlpitch*pi) * twirlscale * sqr(1-d/twirlfade)) + center2;
  2940.  
  2941.             }
  2942.             else if  ((twirltype == 1))
  2943.             {// forward and back
  2944.                 pixel = (pixel-center2) * (1 - cos(d*twirlpitch*pi) * twirlscale * sqr(1-d/twirlfade)) + center2;
  2945.  
  2946.             }
  2947.             else if  ((twirltype == 2))
  2948.             {// in and out
  2949.                 d2 = atan(imag(pixel-center2)/real(pixel-center2));
  2950.                 if  ((real(d2) < 0))
  2951.                 {// pointing to left
  2952.                     d2 = d2 + pi;// rotate 180 degrees
  2953.                 }
  2954.                 if  ((d2 < 0))
  2955.                 {// negative angle (we want 0 < atan < pi*2)
  2956.                     d2 = d2 + pi * 2;// rotate 360 degrees
  2957.                 }
  2958.                 pixel = (pixel-center2) * (1 - cos(d2*twirlpitch) * twirlscale * sqr(1-d/twirlfade)) + center2;
  2959.  
  2960.             }
  2961.             else if  ((twirltype == 3))
  2962.             {// back and forth
  2963.                 d2 = atan(imag(pixel-center2)/real(pixel-center2));
  2964.                 if  ((real(d2) < 0))
  2965.                 {// pointing to left
  2966.                     d2 = d2 + pi;// rotate 180 degrees
  2967.                 }
  2968.                 if  ((d2 < 0))
  2969.                 {// negative angle (we want 0 < atan < pi*2)
  2970.                     d2 = d2 + pi * 2;// rotate 360 degrees
  2971.                 }
  2972.                 pixel = (pixel-center2) * (0,1) ^ (cos(d2*twirlpitch) * twirlscale * sqr(1-d/twirlfade)) + center2;
  2973.  
  2974.             }
  2975.         }
  2976.   
  2977.     }
  2978.     void description(void)
  2979.     {
  2980.         this.title = "Ripples";
  2981.         this.helpfile = "dmj-pub\dmj-pub-uf-ripples.htm";
  2982.  
  2983.    
  2984.         twirlcenter.caption = "Ripple Center";
  2985.         twirlcenter.default = (0,0);
  2986.         twirlcenter.hint = "Sets the center of the ripples.";
  2987.   
  2988.    
  2989.         centermove.caption = "Use Screen Center";
  2990.         centermove.default = TRUE;
  2991.         centermove.hint = "If set, ripples will be around the center of the window, regardless of the Ripple Center setting.";
  2992.   
  2993.    
  2994.         twirlscale.caption = "Ripple Strength";
  2995.         twirlscale.default = 0.25;
  2996.         twirlscale.hint = "Sets the height of the ripples.";
  2997.   
  2998.    
  2999.         twirlpitch.caption = "Ripple Frequency";
  3000.         twirlpitch.default = 10.0;
  3001.         twirlpitch.min = 0.0;
  3002.         twirlpitch.hint = "Frequency of ripples; higher values will give more densely packed ripples.";
  3003.   
  3004.    
  3005.         twirlfade.caption = "Ripple Fade";
  3006.         twirlfade.default = 1.0;
  3007.         twirlfade.min = 0.00000001;
  3008.         twirlfade.hint = "Distance at which ripples fade.";
  3009.   
  3010.    
  3011.         twirltype.caption = "Ripple Type";
  3012.         twirltype.default = 1;
  3013.         twirltype.enum = "Side to Side\nForward and Back\nIn and Out\nBack and Forth";
  3014.         twirltype.hint = "Orientation of ripples with respect to the ripple center.";
  3015.   
  3016.     }
  3017. }
  3018.  
  3019.  
  3020. dmj-Unpolar {
  3021. //
  3022. // This transform converts the normal rectangular coordinates
  3023. // used by UF to polar coordinates, such that real(pixel) is
  3024. // the angle and imag(pixel) is the distance. By itself, this
  3025. // can just warp your fractal quite dramatically, but you can
  3026. // also use this in conjuction with the Polar to Rectangular
  3027. // transform to make any other transform (sandwiched between
  3028. // the two) operate on polar coordinates instead of rectangular
  3029. // coordinates.
  3030. //
  3031. parameter complex polcenter;
  3032.  
  3033.     void transform(void)
  3034.     {
  3035.         pixel = cabs(pixel-polcenter) + flip(atan2(pixel-polcenter));
  3036.  
  3037.     }
  3038.     void description(void)
  3039.     {
  3040.         this.title = "Rectangular to Polar";
  3041.         this.helpfile = "dmj-pub\dmj-pub-uf-r2p.htm";
  3042.   
  3043.    
  3044.         polcenter.caption = "Polar Center";
  3045.         polcenter.default = (0,0);
  3046.         polcenter.hint = "This is the center of the polar coordinate system.";
  3047.   
  3048.     }
  3049. }
  3050.  
  3051.  
  3052. dmj-Unspiral {
  3053. //
  3054. // This undoes a spiral, straightening the arms.
  3055. // You will have to play a bit to get this to
  3056. // exactly match. You can of course also use this
  3057. // to APPLY a spiral transformation. :-)
  3058. //
  3059. complex center2;
  3060. parameter complex spicenter;
  3061. parameter bool centermove;
  3062. complex z2;
  3063. parameter real spipower;
  3064.  
  3065.     void transform(void)
  3066.     {
  3067.         center2 = spicenter;
  3068.         if  ((centermove))
  3069.         {
  3070.             center2 = center;
  3071.         }
  3072.         z2 = pixel - center2;
  3073.         pixel = (z2)*(0,1)^(log(cabs(z2))*spipower) + center2;
  3074.  
  3075.     }
  3076.     void description(void)
  3077.     {
  3078.         this.title = "Unspiral";
  3079.         this.helpfile = "dmj-pub\dmj-pub-uf-unspiral.htm";
  3080.  
  3081.    
  3082.         spicenter.caption = "Spiral Center";
  3083.         spicenter.default = (0,0);
  3084.         spicenter.hint = "Sets the center of the spiral.  Use the eyedropper to pick the center of the spiral.";
  3085.   
  3086.    
  3087.         centermove.caption = "Use Screen Center";
  3088.         centermove.default = TRUE;
  3089.         centermove.hint = "If set, the spiral is assumed to be at the center of the window, regardless of the Spiral Center setting.";
  3090.   
  3091.    
  3092.         spipower.caption = "Spiral Power";
  3093.         spipower.default = 1.0;
  3094.         spipower.hint = "Sets the 'tightness' of the spiral.  Tweak this until the spiral arms are straight.";
  3095.   
  3096.     }
  3097. }
  3098.  
  3099.  
  3100.